package topin.facecat.FaceCat.UI

import facecat.topin.core.*
import topin.facecat.FaceCat.Service.SecurityData
import java.text.*;
import java.util.*;


/**
 * 图表视图
 */
open class FCChart() : FCView() {
    var m_autoFillHScale = false //是否填充满X轴
    var m_allowDragChartDiv = false //是否允许拖拽图层
    var m_candleMax = 0.0 //蜡烛线的最大值
    var m_candleMin = 0.0 //蜡烛线的最小值
    var m_candleMaxRight = 0.0 //蜡烛线的右轴最大值
    var m_candleMinRight = 0.0 //蜡烛线的右轴最小值
    var m_crossTipColor = FCColor.rgb(50, 50, 50) //十字线标识的颜色
    var m_crossLineColor = FCColor.rgb(100, 100, 100) //十字线的颜色
    var m_candlePaddingTop = 30 //图表层的上边距
    var m_candlePaddingBottom = 30 //图表层的下边距
    var m_candleDigit = 2 //图表层保留小数的位数
    var m_candleDivPercent = 0.5 //图表层的占比
    var m_crossStopIndex = -1 //鼠标停留位置
    var m_cycle = "day" //周期
    var m_datas: ArrayList<SecurityData>? = ArrayList() //子节点
    var m_downColor = FCColor.rgb(15, 193, 118) //下跌颜色
    var m_firstVisibleIndex = -1 //起始可见的索引
    var m_gridColor = FCColor.rgb(150, 150, 150) //网格颜色
    var m_lastVisibleIndex = -1 //结束可见的索引
    var m_leftVScaleWidth = 80 //左轴宽度
    var m_lastRecordIsVisible = true //最后记录是否可见
    var m_lastVisibleKey = 0.0 //最后可见的主键
    var m_hScalePixel = 11.0 //蜡烛线的宽度
    var m_hScaleHeight = 30 //X轴的高度
    var m_hScaleTextDistance = 10 //X轴的文字间隔
    var m_hScaleFormat = "" //X轴的格式化字符，例如YYYY-mm-dd HH:MM:SS
    var m_indMax = 0.0 //指标层的最大值
    var m_indMin = 0.0 //指标的最小值
    var m_indMax2 = 0.0 //指标层2的最大值
    var m_indMin2 = 0.0 //指标层2的最小值
    var m_indMaxRight = 0.0 //指标层的右轴最大值
    var m_indMinRight = 0.0 //指标层的右轴最小值
    var m_indMax2Right = 0.0 //指标层2的右轴最大值
    var m_indMin2Right = 0.0 //指标层2的右轴最小值
    var m_indDigit = 2 //指标层保留小数的位数
    var m_indDigit2 = 2 //指标层2保留小数的位数
    var m_indDivPercent = 0.3 //指标层的占比
    var m_indDivPercent2 = 0.0 //指标层2的占比
    var m_indPaddingTop = 20 //指标层的上边距
    var m_indPaddingBottom = 20 //指标层的下边距
    var m_indPaddingTop2 = 20 //指标层2的上边距
    var m_indPaddingBottom2 = 20 //指标层2的下边距
    var m_indicatorColors = ArrayList<Long>() //扩展图形
    var m_lastValidIndex = -1 //最后有效数据索引
    var m_lineWidthChart = 1f
    var m_mainIndicator = "" //主图指标
    var m_magnitude = 1 //成交量的比例
    var m_midColor = FCColor.None //中间颜色
    var m_offsetX = 0f //横向绘图偏移
    var m_plots = ArrayList<FCPlot>() //画线
    var m_plotPointSizeChart = 20 //画线的选中点大小
    var m_rightVScaleWidth = 0 //右轴宽度
    var m_rightSpace = 0 //右侧空间
    var m_scaleColor = FCColor.rgb(100, 100, 100) //刻度的颜色
    var m_showIndicator = "" //显示指标
    var m_showIndicator2 = "" //显示指标2
    var m_showCrossLine = false //是否显示十字线
    var m_selectPlotPoint = -1 //选中画线的点
    var m_startMovePlot = false //选中画线
    var m_selectShape = "" //选中的图形
    var m_selectShapeEx = "" //选中的图形信息
    var m_shapes = ArrayList<BaseShape>() //扩展图形
    var m_sPlot: FCPlot? = null //选中的线条
    var m_targetOldX = 0f //缩小时旧的位置1
    var m_targetOldX2 = 0f //放大时旧的位置2
    var m_touchPosition = FCPoint(0, 0) //鼠标坐标
    var m_trendColor = FCColor.rgb(0, 0, 0) //分时线的颜色
    var m_volMax = 0.0 //成交量层的最大值
    var m_volMin = 0.0 //成交量层的最小值
    var m_volMaxRight = 0.0 //成交量层的右轴最大值
    var m_volMinRight = 0.0 //成交量层的右轴最小值
    var m_volDigit = 0 //成交量层保留小数的位数
    var m_volDivPercent = 0.2 //成交量层的占比
    var m_volPaddingTop = 20 //成交量层的上边距
    var m_volPaddingBottom = 0 //成交量层的下边距
    var m_vScaleDistance = 35 //纵轴的间隔
    var m_vScaleType = "standard" //纵轴的类型 log10代表指数坐标
    var m_upColor = FCColor.rgb(219, 68, 83) //上涨颜色
    var m_kChart = 0.0
    var m_bChart = 0.0
    var m_oXChart = 0.0
    var m_oYChart = 0.0
    var m_rChart = 0.0
    var m_gridStep = 0.0 //网格计算临时变量
    var m_gridDigit = 0 //网格计算临时变量

    //拖动滚动的缓存
    var m_firstIndexCache = -1
    var m_firstTouchIndexCache = -1
    var m_firstTouchPointCache = FCPoint(0, 0)
    var m_lastIndexCache = -1
    var m_secondTouchIndexCache = -1
    var m_secondTouchPointCache = FCPoint(0, 0)
    var m_firstPaddingTop = 0
    var m_firtstPaddingBottom = 0
    var m_touchDownPoint = FCPoint(0, 0)
    var m_addingPlot = ""
    var m_x4Chart = 0.0
    var m_y4Chart = 0.0
    var m_nHighChart = 0.0
    var m_nLowChart = 0.0
    var m_xChart = 0.0
    var m_yChart = 0.0
    var m_wChart = 0.0
    var m_hChart = 0.0
    var m_upSubValue = 0.0
    var m_downSubValue = 0.0
    var m_candleStyle = "rect"
    var m_barStyle = "rect"
    var m_firstOpen = 0.0
    var m_hScaleTextColor = FCColor.None //横轴的颜色
    var m_vScaleTextColor = FCColor.None //纵轴的颜色
    var m_allema26 = ArrayList<Double>()
    var m_allema12 = ArrayList<Double>()
    var m_alldifarr = ArrayList<Double>()
    var m_alldeaarr = ArrayList<Double>()
    var m_allmacdarr = ArrayList<Double>()
    var m_bollUp = ArrayList<Double>()
    var m_bollDown = ArrayList<Double>()
    var m_bollMid = ArrayList<Double>()
    var m_bias1 = ArrayList<Double>()
    var m_bias2 = ArrayList<Double>()
    var m_bias3 = ArrayList<Double>()
    var m_kdjK = ArrayList<Double>()
    var m_kdjD = ArrayList<Double>()
    var m_kdjJ = ArrayList<Double>()
    var m_rsi1 = ArrayList<Double>()
    var m_rsi2 = ArrayList<Double>()
    var m_rsi3 = ArrayList<Double>()
    var m_roc = ArrayList<Double>()
    var m_rocMa = ArrayList<Double>()
    var m_wr1 = ArrayList<Double>()
    var m_wr2 = ArrayList<Double>()
    var m_cci = ArrayList<Double>()
    var m_bbi = ArrayList<Double>()
    var m_trix = ArrayList<Double>()
    var m_trixMa = ArrayList<Double>()
    var m_dma1 = ArrayList<Double>()
    var m_dma2 = ArrayList<Double>()
    var m_ma5 = ArrayList<Double>()
    var m_ma10 = ArrayList<Double>()
    var m_ma20 = ArrayList<Double>()
    var m_ma30 = ArrayList<Double>()
    var m_ma120 = ArrayList<Double>()
    var m_ma250 = ArrayList<Double>()
    var m_closeArr = ArrayList<Double>()

    init {
        m_indicatorColors.add(FCColor.rgb(100, 100, 100))
        m_indicatorColors.add(FCColor.rgb(206, 147, 27))
        m_indicatorColors.add(FCColor.rgb(150, 0, 150))
        m_indicatorColors.add(FCColor.rgb(255, 0, 0))
        m_indicatorColors.add(FCColor.rgb(0, 150, 150))
        m_indicatorColors.add(FCColor.rgb(0, 150, 0))
        m_indicatorColors.add(FCColor.rgb(59, 174, 218))
        m_indicatorColors.add(FCColor.rgb(50, 50, 50))
    }

    /**
     * 添加画线
     * @params firstTouch 是否第一次触摸
     * @params firstPoint 第一次触摸的坐标
     * @params secondTouch 是否第二次触摸
     * @params secondPoint 第二次触摸的坐标
     */
    fun addPlotDefault(
        firstTouch: Boolean,
        firstPoint: FCPoint,
        secondTouch: Boolean,
        secondPoint: FCPoint?,
        darkOrLight: String
    ) {
        val mp = firstPoint
        if (mp.y < candleDivHeight) {
            val touchIndex = getChartIndex(mp)
            if (touchIndex >= m_firstVisibleIndex &&
                touchIndex <= m_lastVisibleIndex
            ) {
                if (m_addingPlot == "FiboTimezone") {
                    val fIndex = touchIndex
                    val fDate = getChartDateByIndex(fIndex)
                    val y = getChartValue(mp)
                    val newPlot = FCPlot()
                    if (darkOrLight == "light") {
                        newPlot.m_lineColor = FCColor.rgb(0, 0, 0)
                        newPlot.m_pointColor = FCColor.rgba(0, 0, 0, 125)
                    } else {
                        newPlot.m_lineColor = FCColor.rgb(255, 255, 255)
                        newPlot.m_pointColor = FCColor.rgba(255, 255, 255, 125)
                    }
                    newPlot.m_key1 = fDate
                    newPlot.m_value1 = y
                    newPlot.m_plotType = m_addingPlot
                    m_plots.add(newPlot)
                    m_sPlot = null
                    val selectedPlot = selectPlot(mp)
                    if (selectedPlot != null) {
                        m_sPlot = selectedPlot
                    }
                } else if (m_addingPlot == "Triangle" || m_addingPlot == "CircumCycle" || m_addingPlot == "ParalleGram" || m_addingPlot == "AngleLine" || m_addingPlot == "Parallel" || m_addingPlot == "SymmetricTriangle") {
                    val eIndex = touchIndex
                    val bIndex = eIndex - 5
                    if (bIndex >= 0) {
                        val fDate = getChartDateByIndex(bIndex)
                        val sDate = getChartDateByIndex(eIndex)
                        val y = getChartValue(mp)
                        val newPlot = FCPlot()
                        if (darkOrLight == "light") {
                            newPlot.m_lineColor = FCColor.rgb(0, 0, 0)
                            newPlot.m_pointColor = FCColor.rgba(0, 0, 0, 125)
                        } else {
                            newPlot.m_lineColor = FCColor.rgb(255, 255, 255)
                            newPlot.m_pointColor = FCColor.rgba(255, 255, 255, 125)
                        }
                        newPlot.m_key1 = fDate
                        newPlot.m_value1 = y
                        newPlot.m_key2 = sDate
                        newPlot.m_value2 = y
                        newPlot.m_key3 = sDate
                        newPlot.m_value3 = m_candleMin + (m_candleMax - m_candleMin) / 2
                        newPlot.m_plotType = m_addingPlot
                        m_plots.add(newPlot)
                        m_sPlot = null
                        val selectedPlot = selectPlot(mp)
                        if (selectedPlot != null) {
                            m_sPlot = selectedPlot
                        }
                    }
                } else {
                    val eIndex = touchIndex
                    val bIndex = eIndex - 5
                    if (bIndex >= 0) {
                        val fDate = getChartDateByIndex(bIndex)
                        val sDate = getChartDateByIndex(eIndex)
                        val y = getChartValue(mp)
                        val newPlot = FCPlot()
                        if (darkOrLight == "light") {
                            newPlot.m_lineColor = FCColor.rgb(0, 0, 0)
                            newPlot.m_pointColor = FCColor.rgba(0, 0, 0, 125)
                        } else {
                            newPlot.m_lineColor = FCColor.rgb(255, 255, 255)
                            newPlot.m_pointColor = FCColor.rgba(255, 255, 255, 125)
                        }
                        newPlot.m_key1 = fDate
                        newPlot.m_value1 = y
                        newPlot.m_key2 = sDate
                        newPlot.m_value2 = y
                        newPlot.m_plotType = m_addingPlot
                        m_plots.add(newPlot)
                        m_sPlot = null
                        val selectedPlot = selectPlot(mp)
                        if (selectedPlot != null) {
                            m_sPlot = selectedPlot
                        }
                    }
                }
            }
        }
    }

    /**
     * 计算平均值
     * @params list 集合
     */
    fun avgValue(list: ArrayList<Double>): Double {
        var sum = 0.0
        val length = list.size
        if (length > 0) {
            for (i in 0 until length) {
                sum += list[i]
            }
            return sum / length
        }
        return 0.0
    }

    /**
     * 计算坐标轴
     * @params min 最小值
     * @params max 最大值
     * @params yLen 长度
     * @params maxSpan 最大间隔
     * @params minSpan 最小间隔
     * @params defCount 数量
     */
    fun chartGridScale(
        min: Double,
        max: Double,
        yLen: Int,
        maxSpan: Double,
        minSpan: Double,
        defCount: Int
    ): Double {
        val sub = max - min
        val nMinCount = Math.ceil(yLen / maxSpan).toInt()
        val nMaxCount = Math.floor(yLen / minSpan).toInt()
        var nCount = defCount
        var logStep = sub / nCount
        var start = false
        var divisor = 0.0
        var i = 0
        var nTemp = 0
        m_gridStep = 0.0
        m_gridDigit = 0
        nCount = if (nMinCount > nCount) nMinCount else nCount
        nCount = if (nMaxCount > nCount) nCount else nMaxCount
        nCount = if (nCount > 1) nCount else 1
        i = 15
        while (i >= -6) {
            divisor = Math.pow(10.0, i.toDouble())
            if (divisor < 1) {
                m_gridDigit++
            }
            nTemp = Math.floor(logStep / divisor).toInt()
            if (start) {
                if (nTemp < 4) {
                    if (m_gridDigit > 0) {
                        m_gridDigit--
                    }
                } else if (nTemp >= 4 && nTemp <= 6) {
                    nTemp = 5
                    m_gridStep += nTemp * divisor
                } else {
                    m_gridStep += 10 * divisor
                    if (m_gridDigit > 0) {
                        m_gridDigit--
                    }
                }
                break
            } else if (nTemp > 0) {
                m_gridStep = nTemp * divisor + m_gridStep
                logStep -= m_gridStep
                start = true
            }
            i--
        }
        return 0.0
    }

    /**
     * 计算最大最小值
     */
    fun calculateChartMaxMin() {
        m_candleMax = 0.0
        m_candleMin = 0.0
        m_volMax = 0.0
        m_volMin = 0.0
        m_indMin = 0.0
        m_indMin = 0.0
        var load1 = false
        var load2 = false
        var load3 = false
        var load4 = false
        val isTrend = m_cycle == "trend"
        var firstOpen = m_firstOpen
        if (m_datas!!.size > 0) {
            var lastValidIndex = m_lastVisibleIndex
            if (m_lastValidIndex != -1) {
                lastValidIndex = m_lastValidIndex
            }
            for (i in m_firstVisibleIndex..lastValidIndex) {
                if (i == m_firstVisibleIndex) {
                    if (isTrend) {
                        m_candleMax = m_datas!![i].m_close
                        m_candleMin = m_datas!![i].m_close
                        if (firstOpen == 0.0) {
                            firstOpen = m_datas!![i].m_close
                        }
                    } else {
                        m_candleMax = m_datas!![i].m_high
                        m_candleMin = m_datas!![i].m_low
                    }
                    m_volMax = m_datas!![i].m_volume
                    load1 = true
                    load2 = true
                    if (m_showIndicator == "MACD") {
                        m_indMax = m_alldifarr[i]
                        m_indMin = m_alldifarr[i]
                        load3 = true
                    } else if (m_showIndicator == "KDJ") {
                        m_indMax = m_kdjK[i]
                        m_indMin = m_kdjK[i]
                        load3 = true
                    } else if (m_showIndicator == "RSI") {
                        m_indMax = m_rsi1[i]
                        m_indMin = m_rsi1[i]
                        load3 = true
                    } else if (m_showIndicator == "BIAS") {
                        m_indMax = m_bias1[i]
                        m_indMin = m_bias1[i]
                        load3 = true
                    } else if (m_showIndicator == "ROC") {
                        m_indMax = m_roc[i]
                        m_indMin = m_roc[i]
                        load3 = true
                    } else if (m_showIndicator == "WR") {
                        m_indMax = m_wr1[i]
                        m_indMin = m_wr1[i]
                        load3 = true
                    } else if (m_showIndicator == "CCI") {
                        m_indMax = m_cci[i]
                        m_indMin = m_cci[i]
                        load3 = true
                    } else if (m_showIndicator == "BBI") {
                        m_indMax = m_bbi[i]
                        m_indMin = m_bbi[i]
                        load3 = true
                    } else if (m_showIndicator == "TRIX") {
                        m_indMax = m_trix[i]
                        m_indMin = m_trix[i]
                        load3 = true
                    } else if (m_showIndicator == "DMA") {
                        m_indMax = m_dma1[i]
                        m_indMin = m_dma1[i]
                        load3 = true
                    }
                    if (m_showIndicator2 == "MACD") {
                        m_indMax2 = m_alldifarr[i]
                        m_indMin2 = m_alldifarr[i]
                        load4 = true
                    } else if (m_showIndicator2 == "KDJ") {
                        m_indMax2 = m_kdjK[i]
                        m_indMin2 = m_kdjK[i]
                        load4 = true
                    } else if (m_showIndicator2 == "RSI") {
                        m_indMax2 = m_rsi1[i]
                        m_indMin2 = m_rsi1[i]
                        load4 = true
                    } else if (m_showIndicator2 == "BIAS") {
                        m_indMax2 = m_bias1[i]
                        m_indMin2 = m_bias1[i]
                        load4 = true
                    } else if (m_showIndicator2 == "ROC") {
                        m_indMax2 = m_roc[i]
                        m_indMin2 = m_roc[i]
                        load4 = true
                    } else if (m_showIndicator2 == "WR") {
                        m_indMax2 = m_wr1[i]
                        m_indMin2 = m_wr1[i]
                        load4 = true
                    } else if (m_showIndicator2 == "CCI") {
                        m_indMax2 = m_cci[i]
                        m_indMin2 = m_cci[i]
                        load4 = true
                    } else if (m_showIndicator2 == "BBI") {
                        m_indMax2 = m_bbi[i]
                        m_indMin2 = m_bbi[i]
                        load4 = true
                    } else if (m_showIndicator2 == "TRIX") {
                        m_indMax2 = m_trix[i]
                        m_indMin2 = m_trix[i]
                        load4 = true
                    } else if (m_showIndicator2 == "DMA") {
                        m_indMax2 = m_dma1[i]
                        m_indMin2 = m_dma1[i]
                        load4 = true
                    }
                } else {
                    if (isTrend) {
                        if (m_candleMax < m_datas!![i].m_close) {
                            m_candleMax = m_datas!![i].m_close
                        }
                        if (m_candleMin > m_datas!![i].m_close) {
                            m_candleMin = m_datas!![i].m_close
                        }
                    } else {
                        if (m_candleMax < m_datas!![i].m_high) {
                            m_candleMax = m_datas!![i].m_high
                        }
                        if (m_candleMin > m_datas!![i].m_low) {
                            m_candleMin = m_datas!![i].m_low
                        }
                    }
                    if (m_volMax < m_datas!![i].m_volume) {
                        m_volMax = m_datas!![i].m_volume
                    }
                }
                if (m_showIndicator == "MACD") {
                    if (m_indMax < m_alldifarr[i]) {
                        m_indMax = m_alldifarr[i]
                    }
                    if (m_indMax < m_alldeaarr[i]) {
                        m_indMax = m_alldeaarr[i]
                    }
                    if (m_indMax < m_allmacdarr[i]) {
                        m_indMax = m_allmacdarr[i]
                    }
                    if (m_indMin > m_alldifarr[i]) {
                        m_indMin = m_alldifarr[i]
                    }
                    if (m_indMin > m_alldeaarr[i]) {
                        m_indMin = m_alldeaarr[i]
                    }
                    if (m_indMin > m_allmacdarr[i]) {
                        m_indMin = m_allmacdarr[i]
                    }
                } else if (m_showIndicator == "KDJ") {
                    if (m_indMax < m_kdjK[i]) {
                        m_indMax = m_kdjK[i]
                    }
                    if (m_indMax < m_kdjD[i]) {
                        m_indMax = m_kdjD[i]
                    }
                    if (m_indMax < m_kdjJ[i]) {
                        m_indMax = m_kdjJ[i]
                    }
                    if (m_indMin > m_kdjK[i]) {
                        m_indMin = m_kdjK[i]
                    }
                    if (m_indMin > m_kdjD[i]) {
                        m_indMin = m_kdjD[i]
                    }
                    if (m_indMin > m_kdjJ[i]) {
                        m_indMin = m_kdjJ[i]
                    }
                } else if (m_showIndicator == "RSI") {
                    if (m_indMax < m_rsi1[i]) {
                        m_indMax = m_rsi1[i]
                    }
                    if (m_indMax < m_rsi2[i]) {
                        m_indMax = m_rsi2[i]
                    }
                    if (m_indMax < m_rsi3[i]) {
                        m_indMax = m_rsi3[i]
                    }
                    if (m_indMin > m_rsi1[i]) {
                        m_indMin = m_rsi1[i]
                    }
                    if (m_indMin > m_rsi2[i]) {
                        m_indMin = m_rsi2[i]
                    }
                    if (m_indMin > m_rsi3[i]) {
                        m_indMin = m_rsi3[i]
                    }
                } else if (m_showIndicator == "BIAS") {
                    if (m_indMax < m_bias1[i]) {
                        m_indMax = m_bias1[i]
                    }
                    if (m_indMax < m_bias2[i]) {
                        m_indMax = m_bias2[i]
                    }
                    if (m_indMax < m_bias3[i]) {
                        m_indMax = m_bias3[i]
                    }
                    if (m_indMin > m_bias1[i]) {
                        m_indMin = m_bias1[i]
                    }
                    if (m_indMin > m_bias2[i]) {
                        m_indMin = m_bias2[i]
                    }
                    if (m_indMin > m_bias3[i]) {
                        m_indMin = m_bias3[i]
                    }
                } else if (m_showIndicator == "ROC") {
                    if (m_indMax < m_roc[i]) {
                        m_indMax = m_roc[i]
                    }
                    if (m_indMax < m_rocMa[i]) {
                        m_indMax = m_rocMa[i]
                    }
                    if (m_indMin > m_roc[i]) {
                        m_indMin = m_roc[i]
                    }
                    if (m_indMin > m_rocMa[i]) {
                        m_indMin = m_rocMa[i]
                    }
                } else if (m_showIndicator == "WR") {
                    if (m_indMax < m_wr1[i]) {
                        m_indMax = m_wr1[i]
                    }
                    if (m_indMax < m_wr2[i]) {
                        m_indMax = m_wr2[i]
                    }
                    if (m_indMin > m_wr1[i]) {
                        m_indMin = m_wr1[i]
                    }
                    if (m_indMin > m_wr2[i]) {
                        m_indMin = m_wr2[i]
                    }
                } else if (m_showIndicator == "CCI") {
                    if (m_indMax < m_cci[i]) {
                        m_indMax = m_cci[i]
                    }
                    if (m_indMin > m_cci[i]) {
                        m_indMin = m_cci[i]
                    }
                } else if (m_showIndicator == "BBI") {
                    if (m_indMax < m_bbi[i]) {
                        m_indMax = m_bbi[i]
                    }
                    if (m_indMin > m_bbi[i]) {
                        m_indMin = m_bbi[i]
                    }
                } else if (m_showIndicator == "TRIX") {
                    if (m_indMax < m_trix[i]) {
                        m_indMax = m_trix[i]
                    }
                    if (m_indMax < m_trixMa[i]) {
                        m_indMax = m_trixMa[i]
                    }
                    if (m_indMin > m_trix[i]) {
                        m_indMin = m_trix[i]
                    }
                    if (m_indMin > m_trixMa[i]) {
                        m_indMin = m_trixMa[i]
                    }
                } else if (m_showIndicator == "DMA") {
                    if (m_indMax < m_dma1[i]) {
                        m_indMax = m_dma1[i]
                    }
                    if (m_indMax < m_dma2[i]) {
                        m_indMax = m_dma2[i]
                    }
                    if (m_indMin > m_dma1[i]) {
                        m_indMin = m_dma1[i]
                    }
                    if (m_indMin > m_dma2[i]) {
                        m_indMin = m_dma2[i]
                    }
                }
                if (m_showIndicator2 == "MACD") {
                    if (m_indMax2 < m_alldifarr[i]) {
                        m_indMax2 = m_alldifarr[i]
                    }
                    if (m_indMax2 < m_alldeaarr[i]) {
                        m_indMax2 = m_alldeaarr[i]
                    }
                    if (m_indMax2 < m_allmacdarr[i]) {
                        m_indMax = m_allmacdarr[i]
                    }
                    if (m_indMin2 > m_alldifarr[i]) {
                        m_indMin2 = m_alldifarr[i]
                    }
                    if (m_indMin2 > m_alldeaarr[i]) {
                        m_indMin2 = m_alldeaarr[i]
                    }
                    if (m_indMin2 > m_allmacdarr[i]) {
                        m_indMin2 = m_allmacdarr[i]
                    }
                } else if (m_showIndicator2 == "KDJ") {
                    if (m_indMax2 < m_kdjK[i]) {
                        m_indMax2 = m_kdjK[i]
                    }
                    if (m_indMax2 < m_kdjD[i]) {
                        m_indMax2 = m_kdjD[i]
                    }
                    if (m_indMax2 < m_kdjJ[i]) {
                        m_indMax2 = m_kdjJ[i]
                    }
                    if (m_indMin2 > m_kdjK[i]) {
                        m_indMin2 = m_kdjK[i]
                    }
                    if (m_indMin2 > m_kdjD[i]) {
                        m_indMin2 = m_kdjD[i]
                    }
                    if (m_indMin2 > m_kdjJ[i]) {
                        m_indMin2 = m_kdjJ[i]
                    }
                } else if (m_showIndicator2 == "RSI") {
                    if (m_indMax2 < m_rsi1[i]) {
                        m_indMax2 = m_rsi1[i]
                    }
                    if (m_indMax2 < m_rsi2[i]) {
                        m_indMax2 = m_rsi2[i]
                    }
                    if (m_indMax2 < m_rsi3[i]) {
                        m_indMax2 = m_rsi3[i]
                    }
                    if (m_indMin2 > m_rsi1[i]) {
                        m_indMin2 = m_rsi1[i]
                    }
                    if (m_indMin2 > m_rsi2[i]) {
                        m_indMin2 = m_rsi2[i]
                    }
                    if (m_indMin2 > m_rsi3[i]) {
                        m_indMin2 = m_rsi3[i]
                    }
                } else if (m_showIndicator2 == "BIAS") {
                    if (m_indMax2 < m_bias1[i]) {
                        m_indMax2 = m_bias1[i]
                    }
                    if (m_indMax2 < m_bias2[i]) {
                        m_indMax2 = m_bias2[i]
                    }
                    if (m_indMax2 < m_bias3[i]) {
                        m_indMax2 = m_bias3[i]
                    }
                    if (m_indMin2 > m_bias1[i]) {
                        m_indMin2 = m_bias1[i]
                    }
                    if (m_indMin2 > m_bias2[i]) {
                        m_indMin2 = m_bias2[i]
                    }
                    if (m_indMin2 > m_bias3[i]) {
                        m_indMin2 = m_bias3[i]
                    }
                } else if (m_showIndicator2 == "ROC") {
                    if (m_indMax2 < m_roc[i]) {
                        m_indMax2 = m_roc[i]
                    }
                    if (m_indMax2 < m_rocMa[i]) {
                        m_indMax2 = m_rocMa[i]
                    }
                    if (m_indMin2 > m_roc[i]) {
                        m_indMin2 = m_roc[i]
                    }
                    if (m_indMin2 > m_rocMa[i]) {
                        m_indMin2 = m_rocMa[i]
                    }
                } else if (m_showIndicator2 == "WR") {
                    if (m_indMax2 < m_wr1[i]) {
                        m_indMax2 = m_wr1[i]
                    }
                    if (m_indMax2 < m_wr2[i]) {
                        m_indMax2 = m_wr2[i]
                    }
                    if (m_indMin2 > m_wr1[i]) {
                        m_indMin2 = m_wr1[i]
                    }
                    if (m_indMin2 > m_wr2[i]) {
                        m_indMin2 = m_wr2[i]
                    }
                } else if (m_showIndicator2 == "CCI") {
                    if (m_indMax2 < m_cci[i]) {
                        m_indMax2 = m_cci[i]
                    }
                    if (m_indMin2 > m_cci[i]) {
                        m_indMin2 = m_cci[i]
                    }
                } else if (m_showIndicator2 == "BBI") {
                    if (m_indMax2 < m_bbi[i]) {
                        m_indMax2 = m_bbi[i]
                    }
                    if (m_indMin2 > m_bbi[i]) {
                        m_indMin2 = m_bbi[i]
                    }
                } else if (m_showIndicator2 == "TRIX") {
                    if (m_indMax2 < m_trix[i]) {
                        m_indMax2 = m_trix[i]
                    }
                    if (m_indMax2 < m_trixMa[i]) {
                        m_indMax2 = m_trixMa[i]
                    }
                    if (m_indMin2 > m_trix[i]) {
                        m_indMin2 = m_trix[i]
                    }
                    if (m_indMin2 > m_trixMa[i]) {
                        m_indMin2 = m_trixMa[i]
                    }
                } else if (m_showIndicator2 == "DMA") {
                    if (m_indMax2 < m_dma1[i]) {
                        m_indMax2 = m_dma1[i]
                    }
                    if (m_indMax2 < m_dma2[i]) {
                        m_indMax2 = m_dma2[i]
                    }
                    if (m_indMin2 > m_dma1[i]) {
                        m_indMin2 = m_dma1[i]
                    }
                    if (m_indMin2 > m_dma2[i]) {
                        m_indMin2 = m_dma2[i]
                    }
                }
            }
        }
        if (m_shapes.size > 0) {
            var lastValidIndex = m_lastVisibleIndex
            if (m_lastValidIndex != -1) {
                lastValidIndex = m_lastValidIndex
            }
            for (s in m_shapes.indices) {
                val shape = m_shapes[s]
                if (shape.m_datas.size > 0) {
                    for (i in m_firstVisibleIndex..lastValidIndex) {
                        if (shape.m_divIndex == 0) {
                            if (!load1 && i == m_firstVisibleIndex) {
                                if (shape.m_leftOrRight) {
                                    m_candleMax = shape.m_datas[i]
                                    m_candleMin = shape.m_datas[i]
                                } else {
                                    m_candleMaxRight = shape.m_datas[i]
                                    m_candleMinRight = shape.m_datas[i]
                                }
                                load1 = true
                            } else {
                                if (shape.m_leftOrRight) {
                                    if (shape.m_datas[i] > m_candleMax) {
                                        m_candleMax = shape.m_datas[i]
                                    }
                                    if (shape.m_datas[i] < m_candleMin) {
                                        m_candleMin = shape.m_datas[i]
                                    }
                                } else {
                                    if (shape.m_datas[i] > m_candleMaxRight) {
                                        m_candleMaxRight = shape.m_datas[i]
                                    }
                                    if (shape.m_datas[i] < m_candleMinRight) {
                                        m_candleMinRight = shape.m_datas[i]
                                    }
                                }
                            }
                        } else if (shape.m_divIndex == 1) {
                            if (!load2 && i == m_firstVisibleIndex) {
                                if (shape.m_leftOrRight) {
                                    m_volMax = shape.m_datas[i]
                                    m_volMin = shape.m_datas[i]
                                } else {
                                    m_volMaxRight = shape.m_datas[i]
                                    m_volMinRight = shape.m_datas[i]
                                }
                                load2 = true
                            } else {
                                if (shape.m_leftOrRight) {
                                    if (shape.m_datas[i] > m_volMax) {
                                        m_volMax = shape.m_datas[i]
                                    }
                                    if (shape.m_datas[i] < m_volMin) {
                                        m_volMin = shape.m_datas[i]
                                    }
                                } else {
                                    if (shape.m_datas[i] > m_volMaxRight) {
                                        m_volMaxRight = shape.m_datas[i]
                                    }
                                    if (shape.m_datas[i] < m_volMinRight) {
                                        m_volMinRight = shape.m_datas[i]
                                    }
                                }
                            }
                        } else if (shape.m_divIndex == 2) {
                            if (!load3 && i == m_firstVisibleIndex) {
                                if (shape.m_leftOrRight) {
                                    m_indMax = shape.m_datas[i]
                                    m_indMin = shape.m_datas[i]
                                } else {
                                    m_indMaxRight = shape.m_datas[i]
                                    m_indMinRight = shape.m_datas[i]
                                }
                                load3 = true
                            } else {
                                if (shape.m_leftOrRight) {
                                    if (shape.m_datas[i] > m_indMax) {
                                        m_indMax = shape.m_datas[i]
                                    }
                                    if (shape.m_datas[i] < m_indMin) {
                                        m_indMin = shape.m_datas[i]
                                    }
                                } else {
                                    if (shape.m_datas[i] > m_indMaxRight) {
                                        m_indMaxRight = shape.m_datas[i]
                                    }
                                    if (shape.m_datas[i] < m_indMinRight) {
                                        m_indMinRight = shape.m_datas[i]
                                    }
                                }
                            }
                        } else if (shape.m_divIndex == 3) {
                            if (!load4 && i == m_firstVisibleIndex) {
                                if (shape.m_leftOrRight) {
                                    m_indMax2 = shape.m_datas[i]
                                    m_indMin2 = shape.m_datas[i]
                                } else {
                                    m_indMax2Right = shape.m_datas[i]
                                    m_indMin2Right = shape.m_datas[i]
                                }
                                load4 = true
                            } else {
                                if (shape.m_leftOrRight) {
                                    if (shape.m_datas[i] > m_indMax2) {
                                        m_indMax2 = shape.m_datas[i]
                                    }
                                    if (shape.m_datas[i] < m_indMin2) {
                                        m_indMin2 = shape.m_datas[i]
                                    }
                                } else {
                                    if (shape.m_datas[i] > m_indMax2Right) {
                                        m_indMax2Right = shape.m_datas[i]
                                    }
                                    if (shape.m_datas[i] < m_indMin2Right) {
                                        m_indMin2Right = shape.m_datas[i]
                                    }
                                }
                            }
                        }
                    }
                }
                if (shape.m_datas2.size > 0) {
                    for (i in m_firstVisibleIndex..lastValidIndex) {
                        if (shape.m_divIndex == 0) {
                            if (shape.m_leftOrRight) {
                                if (shape.m_datas2[i] > m_candleMax) {
                                    m_candleMax = shape.m_datas2[i]
                                }
                                if (shape.m_datas2[i] < m_candleMin) {
                                    m_candleMin = shape.m_datas2[i]
                                }
                            } else {
                                if (shape.m_datas2[i] > m_candleMaxRight) {
                                    m_candleMaxRight = shape.m_datas2[i]
                                }
                                if (shape.m_datas2[i] < m_candleMinRight) {
                                    m_candleMinRight = shape.m_datas2[i]
                                }
                            }
                        } else if (shape.m_divIndex == 1) {
                            if (shape.m_leftOrRight) {
                                if (shape.m_datas2[i] > m_volMax) {
                                    m_volMax = shape.m_datas2[i]
                                }
                                if (shape.m_datas2[i] < m_volMin) {
                                    m_volMin = shape.m_datas2[i]
                                }
                            } else {
                                if (shape.m_datas2[i] > m_volMaxRight) {
                                    m_volMaxRight = shape.m_datas2[i]
                                }
                                if (shape.m_datas2[i] < m_volMinRight) {
                                    m_volMinRight = shape.m_datas2[i]
                                }
                            }
                        } else if (shape.m_divIndex == 2) {
                            if (shape.m_leftOrRight) {
                                if (shape.m_datas2[i] > m_indMax) {
                                    m_indMax = shape.m_datas2[i]
                                }
                                if (shape.m_datas2[i] < m_indMin) {
                                    m_indMin = shape.m_datas2[i]
                                }
                            } else {
                                if (shape.m_datas2[i] > m_indMaxRight) {
                                    m_indMaxRight = shape.m_datas2[i]
                                }
                                if (shape.m_datas2[i] < m_indMinRight) {
                                    m_indMinRight = shape.m_datas2[i]
                                }
                            }
                        } else if (shape.m_divIndex == 3) {
                            if (shape.m_leftOrRight) {
                                if (shape.m_datas2[i] > m_indMax2) {
                                    m_indMax2 = shape.m_datas2[i]
                                }
                                if (shape.m_datas2[i] < m_indMin2) {
                                    m_indMin2 = shape.m_datas2[i]
                                }
                            } else {
                                if (shape.m_datas2[i] > m_indMax2Right) {
                                    m_indMax2Right = shape.m_datas2[i]
                                }
                                if (shape.m_datas2[i] < m_indMin2Right) {
                                    m_indMin2Right = shape.m_datas2[i]
                                }
                            }
                        }
                    }
                }
            }
        }
        if (isTrend) {
            val subMax = Math.max(
                Math.abs(m_candleMax - firstOpen),
                Math.abs(m_candleMin - firstOpen)
            )
            m_candleMax = firstOpen + subMax
            m_candleMin = firstOpen - subMax
        } else {
            if (m_candleMax == 0.0 && m_candleMin == 0.0) {
                m_candleMax = 1.0
                m_candleMin = -1.0
            }
            if (m_volMax == 0.0 && m_volMin == 0.0) {
                m_volMax = 1.0
                m_volMin = -1.0
            }
            if (m_indMax == 0.0 && m_indMin == 0.0) {
                m_indMax = 1.0
                m_indMin = -1.0
            }
            if (m_indMax2 == 0.0 && m_indMin2 == 0.0) {
                m_indMax2 = 1.0
                m_indMin2 = -1.0
            }
            if (m_candleMaxRight == 0.0 && m_candleMinRight == 0.0) {
                m_candleMaxRight = 1.0
                m_candleMinRight = -1.0
            }
            if (m_volMaxRight == 0.0 && m_volMinRight == 0.0) {
                m_volMaxRight = 1.0
                m_volMinRight = -1.0
            }
            if (m_indMaxRight == 0.0 && m_indMinRight == 0.0) {
                m_indMaxRight = 1.0
                m_indMinRight = -1.0
            }
            if (m_indMax2Right == 0.0 && m_indMin2Right == 0.0) {
                m_indMax2Right = 1.0
                m_indMin2Right = -1.0
            }
        }
    }

    /**
     * 检查最后可见索引
     */
    fun checkChartLastVisibleIndex() {
        val dataCount = m_datas!!.size
        val workingAreaWidth = chartWorkAreaWidth
        val maxVisibleRecord = getChartMaxVisibleCount(m_hScalePixel, workingAreaWidth.toDouble())
        if (m_firstVisibleIndex < 0) {
            m_firstVisibleIndex = 0
        }
        if (m_lastVisibleIndex >= m_firstVisibleIndex + maxVisibleRecord - 1 || m_lastVisibleIndex < dataCount - 1) {
            m_lastVisibleIndex = m_firstVisibleIndex + maxVisibleRecord - 1
        }
        if (m_lastVisibleIndex > dataCount - 1) {
            m_lastVisibleIndex = dataCount - 1
        }
        if (m_datas!!.size > 0 && m_lastVisibleIndex != -1) {
            m_lastVisibleKey = m_datas!![m_lastVisibleIndex].m_date
            if (m_lastVisibleIndex == m_datas!!.size - 1) {
                m_lastRecordIsVisible = true
            } else {
                m_lastRecordIsVisible = false
            }
        } else {
            m_lastVisibleKey = 0.0
            m_lastRecordIsVisible = true
        }
    }

    /**
     * 清除缓存数据方法
     */
    fun clearDataArr() {
        m_allema12 = ArrayList()
        m_allema26 = ArrayList()
        m_alldifarr = ArrayList()
        m_alldeaarr = ArrayList()
        m_allmacdarr = ArrayList()
        m_bollUp = ArrayList()
        m_bollDown = ArrayList()
        m_bollMid = ArrayList()
        m_bias1 = ArrayList()
        m_bias2 = ArrayList()
        m_bias3 = ArrayList()
        m_kdjK = ArrayList()
        m_kdjD = ArrayList()
        m_kdjJ = ArrayList()
        m_rsi1 = ArrayList()
        m_rsi2 = ArrayList()
        m_rsi3 = ArrayList()
        m_roc = ArrayList()
        m_rocMa = ArrayList()
        m_wr1 = ArrayList()
        m_wr2 = ArrayList()
        m_cci = ArrayList()
        m_bbi = ArrayList()
        m_trix = ArrayList()
        m_trixMa = ArrayList()
        m_dma1 = ArrayList()
        m_dma2 = ArrayList()
        m_ma5 = ArrayList()
        m_ma10 = ArrayList()
        m_ma20 = ArrayList()
        m_ma30 = ArrayList()
        m_ma120 = ArrayList()
        m_ma250 = ArrayList()
    }

    /**
     * 获取数据
     */
    fun calcChartIndicator() {
        clearDataArr()
        val closeArr = ArrayList<Double>()
        val highArr = ArrayList<Double>()
        val lowArr = ArrayList<Double>()
        if (m_datas!!.size > 0) {
            for (i in m_datas!!.indices) {
                closeArr.add(m_datas!![i].m_close)
                highArr.add(m_datas!![i].m_high)
                lowArr.add(m_datas!![i].m_low)
            }
        }
        m_closeArr = closeArr
        if (m_mainIndicator == "BOLL") {
            getBollData(closeArr, 20, m_bollUp, m_bollMid, m_bollDown)
        } else if (m_mainIndicator == "MA") {
            m_ma5 = maValue(closeArr, 5)
            m_ma10 = maValue(closeArr, 10)
            m_ma20 = maValue(closeArr, 20)
            m_ma30 = maValue(closeArr, 30)
            m_ma120 = maValue(closeArr, 120)
            m_ma250 = maValue(closeArr, 250)
        }
        if (m_showIndicator == "BIAS" || m_showIndicator2 == "BIAS") {
            getBIASData(closeArr, 6, 12, 24, m_bias1, m_bias2, m_bias3)
        }
        if (m_showIndicator == "DMA" || m_showIndicator2 == "DMA") {
            getDMAData(closeArr, 10, 50, m_dma1, m_dma2)
        }
        if (m_showIndicator == "BBI" || m_showIndicator2 == "BBI") {
            getBBIData(closeArr, 3, 6, 12, 24, m_bbi)
        }
        if (m_showIndicator == "RSI" || m_showIndicator2 == "RSI") {
            getRSIData(closeArr, 6, 12, 24, m_rsi1, m_rsi2, m_rsi3)
        }
        if (m_showIndicator == "ROC" || m_showIndicator2 == "ROC") {
            getRocData(closeArr, 12, 6, m_roc, m_rocMa)
        }
        if (m_showIndicator == "TRIX" || m_showIndicator2 == "TRIX") {
            getTRIXData(closeArr, 9, m_trix, m_trixMa)
        }
        if (m_showIndicator == "KDJ" || m_showIndicator2 == "KDJ") {
            getKDJData(
                highArr, lowArr, closeArr, 9, 3, 3, m_kdjK, m_kdjD, m_kdjJ
            )
        }
        if (m_showIndicator == "WR" || m_showIndicator2 == "WR") {
            getWRData(highArr, lowArr, closeArr, 5, 10, m_wr1, m_wr2)
        }
        if (m_showIndicator == "CCI" || m_showIndicator2 == "CCI") {
            getCCIData(highArr, lowArr, closeArr, 14, m_cci)
        }
        if (m_showIndicator == "MACD" || m_showIndicator2 == "MACD") {
            //缓存MACD数据
            m_allema12.add(closeArr[0])
            m_allema26.add(closeArr[0])
            m_alldeaarr.add(0.0)
            for (i in 1 until closeArr.size) {
                m_allema12.add(getEMA(12, closeArr[i], m_allema12[i - 1]))
                m_allema26.add(getEMA(26, closeArr[i], m_allema26[i - 1]))
            }
            m_alldifarr = getDIF(m_allema12, m_allema26)
            for (i in 1 until m_alldifarr.size) {
                m_alldeaarr
                    .add(m_alldeaarr[i - 1] * 8 / 10 + m_alldifarr[i] * 2 / 10)
            }
            m_allmacdarr = getMACD(m_alldifarr, m_alldeaarr)
        }
        calculateChartMaxMin()
    }

    /**
     * 绘制线条
     * @params paint 绘图对象
     * @params clipRect 裁剪区域
     * @params divIndex 图层
     * @params datas 数据
     * @params color 颜色
     * @params selected 是否选中
     */
    fun drawChartLines(
        paint: FCPaint,
        clipRect: FCRect?,
        divIndex: Int,
        datas: ArrayList<Double>,
        color: Long?,
        selected: Boolean
    ) {
        val drawPoints = ArrayList<FCPoint>()
        var lastX = 0.0
        var lastY = 0.0
        val maxVisibleRecord = getChartMaxVisibleCount(m_hScalePixel, chartWorkAreaWidth.toDouble())
        var lastValidIndex = m_lastVisibleIndex
        if (m_lastValidIndex != -1) {
            lastValidIndex = m_lastValidIndex
        }
        for (i in m_firstVisibleIndex..lastValidIndex) {
            val x = getChartX(i)
            val value = datas[i]
            val y = getChartY(divIndex, value)
            drawPoints.add(FCPoint(x, y))
            lastX = x.toDouble()
            lastY = y.toDouble()
            if (selected) {
                var kPInterval = maxVisibleRecord / 30
                if (kPInterval < 2) {
                    kPInterval = 3
                }
                if (i % kPInterval == 0) {
                    paint.fillRect(color!!, (x - 3), (y - 3), (x + 3), (y + 3))
                }
            }
        }
        val apt = arrayOfNulls<FCPoint>(drawPoints.size)
        for (i in drawPoints.indices) {
            apt[i] = drawPoints[i]
        }
        paint.drawPolyline(color!!, m_lineWidthChart, 0, apt)
    }

    /**
     * 绘制线条到右轴
     * @params paint 绘图对象
     * @params clipRect 裁剪区域
     * @params divIndex 图层
     * @params datas 数据
     * @params color 颜色
     * @params selected 是否选中
     */
    fun drawChartLinesInRight(
        paint: FCPaint,
        clipRect: FCRect?,
        divIndex: Int,
        datas: ArrayList<Double>,
        color: Long,
        selected: Boolean
    ) {
        val drawPoints = ArrayList<FCPoint>()
        var lastX = 0.0
        var lastY = 0.0
        val maxVisibleRecord = getChartMaxVisibleCount(m_hScalePixel, chartWorkAreaWidth.toDouble())
        var lastValidIndex = m_lastVisibleIndex
        if (m_lastValidIndex != -1) {
            lastValidIndex = m_lastValidIndex
        }
        for (i in m_firstVisibleIndex..lastValidIndex) {
            val x = getChartX(i)
            val value = datas[i]
            val y = getChartYInRight(divIndex, value)
            drawPoints.add(FCPoint(x, y))
            lastX = x.toDouble()
            lastY = y.toDouble()
            if (selected) {
                var kPInterval = maxVisibleRecord / 30
                if (kPInterval < 2) {
                    kPInterval = 3
                }
                if (i % kPInterval == 0) {
                    paint.fillRect(color, (x - 3), (y - 3), (x + 3), (y + 3))
                }
            }
        }
        val apt = arrayOfNulls<FCPoint>(drawPoints.size)
        for (i in drawPoints.indices) {
            apt[i] = drawPoints[i]
        }
        paint.drawPolyline(color, m_lineWidthChart, 0, apt)
    }

    /**
     * 绘制画线工具
     * @params paint 绘图对象
     * @params clipRect 裁剪区
     */
    fun drawChartPlot(paint: FCPaint, clipRect: FCRect) {
        val size = size
        val divHeight = candleDivHeight
        paint.setClip(
            FCRect(
                Math.max(clipRect.left, m_leftVScaleWidth),
                Math.max(clipRect.top, 0),
                Math.min(clipRect.right, size.cx - m_rightVScaleWidth),
                Math.min(clipRect.bottom, divHeight)
            )
        )
        for (i in m_plots.indices) {
            val plot = m_plots[i]
            var index1 = 0
            var index2 = 0
            var index3 = 0
            var mpx1 = 0
            var mpy1 = 0
            var mpx2 = 0
            var mpy2 = 0
            var mpx3 = 0
            var mpy3 = 0
            if (plot.m_plotType == "LRLine" || plot.m_plotType == "LRChannel" || plot.m_plotType == "LRBand") {
                val list = ArrayList<Double>()
                index1 = getChartIndexByDate(plot.m_key1)
                index2 = getChartIndexByDate(plot.m_key2)
                val minIndex = Math.min(index1, index2)
                val maxIndex = Math.max(index1, index2)
                for (j in minIndex..maxIndex) {
                    list.add(m_datas!![j].m_close)
                }
                linearRegressionEquation(list)
                plot.m_value1 = m_bChart
                plot.m_value2 = m_kChart * (maxIndex - minIndex + 1) + m_bChart
            } else if (plot.m_plotType == "BoxLine" || plot.m_plotType == "TironeLevels" || plot.m_plotType == "QuadrantLines") {
                getCandleRange(plot)
                val nHigh = m_nHighChart
                val nLow = m_nLowChart
                index1 = getChartIndexByDate(plot.m_key1)
                index2 = getChartIndexByDate(plot.m_key2)
                plot.m_key1 = getChartDateByIndex(Math.min(index1, index2))
                plot.m_key2 = getChartDateByIndex(Math.max(index1, index2))
                plot.m_value1 = nHigh
                plot.m_value2 = nLow
            }
            if (plot.m_key1 > 0) {
                index1 = getChartIndexByDate(plot.m_key1)
                mpx1 = getChartX(index1)
                mpy1 = getChartY(0, plot.m_value1)
                if (m_sPlot == plot) {
                    paint.fillEllipse(
                        plot.m_pointColor,
                        (mpx1 - m_plotPointSizeChart),
                        (mpy1 - m_plotPointSizeChart),
                        (mpx1 + m_plotPointSizeChart),
                        (mpy1 + m_plotPointSizeChart)
                    )
                }
            }
            if (plot.m_key2 > 0) {
                index2 = getChartIndexByDate(plot.m_key2)
                mpx2 = getChartX(index2)
                mpy2 = getChartY(0, plot.m_value2)
                if (m_sPlot == plot) {
                    paint.fillEllipse(
                        plot.m_pointColor,
                        (mpx2 - m_plotPointSizeChart),
                        (mpy2 - m_plotPointSizeChart),
                        (mpx2 + m_plotPointSizeChart),
                        (mpy2 + m_plotPointSizeChart)
                    )
                }
            }
            if (plot.m_key3 > 0) {
                index3 = getChartIndexByDate(plot.m_key3)
                mpx3 = getChartX(index3)
                mpy3 = getChartY(0, plot.m_value3)
                if (m_sPlot == plot) {
                    paint.fillEllipse(
                        plot.m_pointColor,
                        (mpx3 - m_plotPointSizeChart),
                        (mpy3 - m_plotPointSizeChart),
                        (mpx3 + m_plotPointSizeChart),
                        (mpy3 + m_plotPointSizeChart)
                    )
                }
            }
            if (plot.m_plotType == "Line") {
                lineXY(mpx1.toDouble(), mpy1.toDouble(), mpx2.toDouble(), mpy2.toDouble(), 0.0, 0.0)
                if (mpx2 == mpx1) {
                    paint.drawLine(
                        plot.m_lineColor, plot.m_lineWidth, 0, mpx1, 0, mpx1, divHeight
                    )
                } else {
                    val newX1 = m_leftVScaleWidth.toDouble()
                    val newY1 = newX1 * m_kChart + m_bChart
                    val newX2 = (size.cx - m_rightVScaleWidth).toDouble()
                    val newY2 = newX2 * m_kChart + m_bChart
                    paint.drawLine(
                        plot.m_lineColor,
                        plot.m_lineWidth,
                        0,
                        newX1.toInt(),
                        newY1.toInt(),
                        newX2.toInt(),
                        newY2.toInt()
                    )
                }
            } else if (plot.m_plotType == "ArrowSegment") {
                var arrowSize = 24
                var slopy = 0.0
                var cosy = 0.0
                var siny = 0.0
                slopy = Math.atan2((mpy1 - mpy2).toDouble(), (mpx1 - mpx2).toDouble())
                cosy = Math.cos(slopy)
                siny = Math.sin(slopy)
                val ptPoint = FCPoint(0, 0)
                ptPoint.x = mpx2
                ptPoint.y = mpy2
                val pts = ArrayList<FCPoint>()
                pts.add(FCPoint(0, 0))
                pts.add(FCPoint(0, 0))
                pts.add(FCPoint(0, 0))
                pts[0] = ptPoint
                pts[1] = FCPoint(
                    (ptPoint.x + (arrowSize * cosy - (arrowSize / 2.0 * siny) + 0.5)).toInt(),
                    (ptPoint.y + ((arrowSize * siny) + (arrowSize / 2.0 * cosy) + 0.5)).toInt()
                )
                pts[2] = FCPoint(
                    (ptPoint.x + ((arrowSize * cosy) + (arrowSize / 2.0 * siny) + 0.5)).toInt(),
                    (ptPoint.y - (arrowSize / 2.0 * cosy - arrowSize * siny + 0.5)).toInt()
                )
                arrowSize = 20
                val ptPoint2 = FCPoint(0, 0)
                ptPoint2.x = mpx2
                ptPoint2.y = mpy2
                val pts2 = ArrayList<FCPoint>()
                pts2.add(FCPoint(0, 0))
                pts2.add(FCPoint(0, 0))
                pts2.add(FCPoint(0, 0))
                pts2[0] = ptPoint2
                pts2[1] = FCPoint(
                    (ptPoint2.x + (arrowSize * cosy - (arrowSize / 2.0 * siny) + 0.5)).toInt(),
                    (ptPoint2.y + ((arrowSize * siny) + (arrowSize / 2.0 * cosy) + 0.5)).toInt()
                )
                pts2[2] = FCPoint(
                    (ptPoint2.x + ((arrowSize * cosy) + (arrowSize / 2.0 * siny) + 0.5)).toInt(),
                    (ptPoint2.y - (arrowSize / 2.0 * cosy - arrowSize * siny + 0.5)).toInt()
                )
                lineXY(
                    pts2[1].x.toDouble(),
                    pts2[1].y.toDouble(),
                    pts2[2].x.toDouble(),
                    pts2[2].y.toDouble(),
                    0.0,
                    0.0
                )
                var newX1 = 0.0
                var newY1 = 0.0
                var newX2 = 0.0
                var newY2 = 0.0
                if (pts2[1].x > pts2[2].x) {
                    newX1 = (pts2[2].x + (pts2[1].x - pts2[2].x) / 3).toDouble()
                    newX2 = (pts2[2].x + (pts2[1].x - pts2[2].x) * 2 / 3).toDouble()
                } else {
                    newX1 = (pts2[1].x + (pts2[2].x - pts2[1].x) / 3).toDouble()
                    newX2 = (pts2[1].x + (pts2[2].x - pts2[1].x) * 2 / 3).toDouble()
                }
                if (m_kChart == 0.0 && m_bChart == 0.0) {
                    if (pts2[1].y > pts2[2].y) {
                        newY1 = (pts2[2].y + (pts2[1].y - pts2[2].y) / 3).toDouble()
                        newY2 = (pts2[2].y + (pts2[1].y - pts2[2].y) * 2 / 3).toDouble()
                    } else {
                        newY1 = (pts2[1].y + (pts2[2].y - pts2[1].y) / 3).toDouble()
                        newY2 = (pts2[1].y + (pts2[2].y - pts2[1].y) * 2 / 3).toDouble()
                    }
                } else {
                    newY1 = m_kChart * newX1 + m_bChart
                    newY2 = m_kChart * newX2 + m_bChart
                }
                pts2[1] = FCPoint(newX1.toInt(), newY1.toInt())
                pts2[2] = FCPoint(newX2.toInt(), newY2.toInt())
                val drawPoints = ArrayList<FCPoint>()
                drawPoints.add(FCPoint(0, 0))
                drawPoints.add(FCPoint(0, 0))
                drawPoints.add(FCPoint(0, 0))
                drawPoints.add(FCPoint(0, 0))
                drawPoints.add(FCPoint(0, 0))
                drawPoints.add(FCPoint(0, 0))
                drawPoints[0] = FCPoint(ptPoint.x, ptPoint.y)
                drawPoints[1] = FCPoint(pts[1].x, pts[1].y)
                if (mpy1 >= mpy2) {
                    drawPoints[2] = FCPoint(pts2[1].x, pts2[1].y)
                } else {
                    drawPoints[2] = FCPoint(pts2[2].x, pts2[2].y)
                }
                drawPoints[3] = FCPoint(mpx1, mpy1)
                if (mpy1 >= mpy2) {
                    drawPoints[4] = FCPoint(pts2[2].x, pts2[2].y)
                } else {
                    drawPoints[4] = FCPoint(pts2[1].x, pts2[1].y)
                }
                drawPoints[5] = FCPoint(pts[2].x, pts[2].y)
                val apt = arrayOfNulls<FCPoint>(drawPoints.size)
                for (j in drawPoints.indices) {
                    apt[i] = drawPoints[i]
                }
                paint.fillPolygon(plot.m_lineColor, apt)
            } else if (plot.m_plotType == "AngleLine") {
                lineXY(mpx1.toDouble(), mpy1.toDouble(), mpx2.toDouble(), mpy2.toDouble(), 0.0, 0.0)
                if (mpx2 == mpx1) {
                    paint.drawLine(
                        plot.m_lineColor, plot.m_lineWidth, 0, mpx1, 0, mpx1, divHeight
                    )
                } else {
                    val newX1 = m_leftVScaleWidth.toDouble()
                    val newY1 = newX1 * m_kChart + m_bChart
                    val newX2 = (size.cx - m_rightVScaleWidth).toDouble()
                    val newY2 = newX2 * m_kChart + m_bChart
                    paint.drawLine(
                        plot.m_lineColor,
                        plot.m_lineWidth,
                        0,
                        newX1.toInt(),
                        newY1.toInt(),
                        newX2.toInt(),
                        newY2.toInt()
                    )
                }
                lineXY(mpx1.toDouble(), mpy1.toDouble(), mpx3.toDouble(), mpy3.toDouble(), 0.0, 0.0)
                if (mpx3 == mpx1) {
                    paint.drawLine(
                        plot.m_lineColor, plot.m_lineWidth, 0, mpx1, 0, mpx1, divHeight
                    )
                } else {
                    val newX1 = m_leftVScaleWidth.toDouble()
                    val newY1 = newX1 * m_kChart + m_bChart
                    val newX2 = (size.cx - m_rightVScaleWidth).toDouble()
                    val newY2 = newX2 * m_kChart + m_bChart
                    paint.drawLine(
                        plot.m_lineColor,
                        plot.m_lineWidth,
                        0,
                        newX1.toInt(),
                        newY1.toInt(),
                        newX2.toInt(),
                        newY2.toInt()
                    )
                }
            } else if (plot.m_plotType == "Parallel") {
                lineXY(mpx1.toDouble(), mpy1.toDouble(), mpx2.toDouble(), mpy2.toDouble(), 0.0, 0.0)
                if (mpx2 == mpx1) {
                    paint.drawLine(
                        plot.m_lineColor, plot.m_lineWidth, 0, mpx1, 0, mpx1, divHeight
                    )
                } else {
                    val newX1 = m_leftVScaleWidth.toDouble()
                    val newY1 = newX1 * m_kChart + m_bChart
                    val newX2 = (size.cx - m_rightVScaleWidth).toDouble()
                    val newY2 = newX2 * m_kChart + m_bChart
                    paint.drawLine(
                        plot.m_lineColor,
                        plot.m_lineWidth,
                        0,
                        newX1.toInt(),
                        newY1.toInt(),
                        newX2.toInt(),
                        newY2.toInt()
                    )
                }
                val newB = mpy3 - m_kChart * mpx3
                if (mpx2 == mpx1) {
                    paint.drawLine(
                        plot.m_lineColor, plot.m_lineWidth, 0, mpx3, 0, mpx3, divHeight
                    )
                } else {
                    val newX1 = m_leftVScaleWidth.toDouble()
                    val newY1 = newX1 * m_kChart + newB
                    val newX2 = (size.cx - m_rightVScaleWidth).toDouble()
                    val newY2 = newX2 * m_kChart + newB
                    paint.drawLine(
                        plot.m_lineColor,
                        plot.m_lineWidth,
                        0,
                        newX1.toInt(),
                        newY1.toInt(),
                        newX2.toInt(),
                        newY2.toInt()
                    )
                }
            } else if (plot.m_plotType == "Percent") {
                val list = getPercentParams(mpy1.toDouble(), mpy2.toDouble())
                val texts = ArrayList<String>()
                texts.add("0%")
                texts.add("25%")
                texts.add("50%")
                texts.add("75%")
                texts.add("100%")
                for (j in list.indices) {
                    paint.drawLine(
                        plot.m_lineColor, plot.m_lineWidth, 0, m_leftVScaleWidth,
                        list[j], size.cx - m_rightVScaleWidth, list[j]
                    )
                    val tSize = paint.textSize(texts[j], font)
                    paint.drawText(
                        texts[j], textColor, font,
                        FCRect(
                            m_leftVScaleWidth + 5,
                            list[j] - tSize.cy - 2,
                            m_leftVScaleWidth + 5 + tSize.cx,
                            list[j] - 2
                        )
                    )
                }
            } else if (plot.m_plotType == "FiboTimezone") {
                var fValue = 1
                val aIndex = index1
                var pos = 1
                paint.drawLine(
                    plot.m_lineColor, plot.m_lineWidth, 0, mpx1, 0, mpx1, divHeight
                )
                val tSize = paint.textSize("1", font)
                paint.drawText(
                    "1",
                    textColor, font, FCRect(mpx1, divHeight - tSize.cy, mpx1 + tSize.cx, divHeight)
                )
                while (aIndex + fValue <= m_lastVisibleIndex) {
                    fValue = fibonacciValue(pos)
                    val newIndex = aIndex + fValue
                    val newX = getChartX(newIndex).toDouble()
                    paint.drawLine(
                        plot.m_lineColor,
                        plot.m_lineWidth,
                        0,
                        newX.toInt(),
                        0,
                        newX.toInt(),
                        divHeight
                    )
                    val tSize2 = paint.textSize(
                        FCTran.doubleToStr(fValue.toDouble()),
                        font
                    )
                    paint.drawText(
                        FCTran.doubleToStr(fValue.toDouble()),
                        textColor, font, FCRect(
                            newX.toInt(),
                            divHeight - tSize2.cy, newX.toInt() + tSize2.cx, divHeight
                        )
                    )
                    pos++
                }
            } else if (plot.m_plotType == "SpeedResist") {
                paint.drawLine(plot.m_lineColor, plot.m_lineWidth, 0, mpx1, mpy1, mpx2, mpy2)
                if (mpx1 != mpx2 && mpy1 != mpy2) {
                    val firstP = FCPoint(mpx2, mpy2 - (mpy2 - mpy1) / 3)
                    val secondP = FCPoint(mpx2, mpy2 - (mpy2 - mpy1) * 2 / 3)
                    val startP = FCPoint(mpx1, mpy1)
                    var fK = 0.0
                    var fB = 0.0
                    var sK = 0.0
                    var sB = 0.0
                    lineXY(
                        startP.x.toDouble(),
                        startP.y.toDouble(),
                        firstP.x.toDouble(),
                        firstP.y.toDouble(),
                        0.0,
                        0.0
                    )
                    fK = m_kChart
                    fB = m_bChart
                    lineXY(
                        startP.x.toDouble(),
                        startP.y.toDouble(),
                        secondP.x.toDouble(),
                        secondP.y.toDouble(),
                        0.0,
                        0.0
                    )
                    sK = m_kChart
                    sB = m_bChart
                    var newYF = 0.0
                    var newYS = 0.0
                    var newX = 0.0
                    if (mpx2 > mpx1) {
                        newYF = fK * (size.cx - m_rightVScaleWidth) + fB
                        newYS = sK * (size.cx - m_rightVScaleWidth) + sB
                        newX = (size.cx - m_rightVScaleWidth).toDouble()
                    } else {
                        newYF = fB
                        newYS = sB
                        newX = m_leftVScaleWidth.toDouble()
                    }
                    paint.drawLine(
                        plot.m_lineColor,
                        plot.m_lineWidth,
                        0,
                        startP.x,
                        startP.y,
                        newX.toInt(),
                        newYF.toInt()
                    )
                    paint.drawLine(
                        plot.m_lineColor,
                        plot.m_lineWidth,
                        0,
                        startP.x,
                        startP.y,
                        newX.toInt(),
                        newYS.toInt()
                    )
                }
            } else if (plot.m_plotType == "FiboFanline") {
                paint.drawLine(plot.m_lineColor, plot.m_lineWidth, 0, mpx1, mpy1, mpx2, mpy2)
                if (mpx1 != mpx2 && mpy1 != mpy2) {
                    val firstP = FCPoint(mpx2, (mpy2 - (mpy2 - mpy1) * 0.382).toInt())
                    val secondP = FCPoint(mpx2, (mpy2 - (mpy2 - mpy1) * 0.5).toInt())
                    val thirdP = FCPoint(mpx2, (mpy2 - (mpy2 - mpy1) * 0.618).toInt())
                    val startP = FCPoint(mpx1, mpy1)
                    val listP = ArrayList<FCPoint>()
                    listP.add(firstP)
                    listP.add(secondP)
                    listP.add(thirdP)
                    val listSize = listP.size
                    for (j in 0 until listSize) {
                        //获取直线参数
                        lineXY(
                            startP.x.toDouble(),
                            startP.y.toDouble(),
                            listP[j].x.toDouble(),
                            listP[j].y.toDouble(),
                            0.0,
                            0.0
                        )
                        var newX = 0.0
                        var newY = 0.0
                        if (mpx2 > mpx1) {
                            newY = m_kChart * (size.cx - m_rightVScaleWidth) +
                                    m_bChart
                            newX = (size.cx - m_rightVScaleWidth).toDouble()
                        } else {
                            newY = m_bChart
                            newX = m_leftVScaleWidth.toDouble()
                        }
                        paint.drawLine(
                            plot.m_lineColor,
                            plot.m_lineWidth,
                            0,
                            startP.x,
                            startP.y,
                            newX.toInt(),
                            newY.toInt()
                        )
                    }
                }
            } else if (plot.m_plotType == "LRLine") {
                paint.drawLine(plot.m_lineColor, plot.m_lineWidth, 0, mpx1, mpy1, mpx2, mpy2)
            } else if (plot.m_plotType == "LRBand") {
                paint.drawLine(plot.m_lineColor, plot.m_lineWidth, 0, mpx1, mpy1, mpx2, mpy2)
                getLRBandRange(plot, m_kChart, m_bChart)
                mpy1 = getChartY(0, plot.m_value1 + m_upSubValue)
                mpy2 = getChartY(0, plot.m_value2 + m_upSubValue)
                paint.drawLine(plot.m_lineColor, plot.m_lineWidth, 0, mpx1, mpy1, mpx2, mpy2)
                mpy1 = getChartY(0, plot.m_value1 - m_downSubValue)
                mpy2 = getChartY(0, plot.m_value2 - m_downSubValue)
                paint.drawLine(plot.m_lineColor, plot.m_lineWidth, 0, mpx1, mpy1, mpx2, mpy2)
            } else if (plot.m_plotType == "LRChannel") {
                getLRBandRange(plot, m_kChart, m_bChart)
                lineXY(mpx1.toDouble(), mpy1.toDouble(), mpx2.toDouble(), mpy2.toDouble(), 0.0, 0.0)
                val rightX = (size.cx - m_rightVScaleWidth).toDouble()
                var rightY = rightX * m_kChart + m_bChart
                paint.drawLine(
                    plot.m_lineColor,
                    plot.m_lineWidth,
                    0,
                    mpx1,
                    mpy1,
                    rightX.toInt(),
                    rightY.toInt()
                )
                mpy1 = getChartY(0, plot.m_value1 + m_upSubValue)
                mpy2 = getChartY(0, plot.m_value2 + m_upSubValue)
                lineXY(mpx1.toDouble(), mpy1.toDouble(), mpx2.toDouble(), mpy2.toDouble(), 0.0, 0.0)
                rightY = rightX * m_kChart + m_bChart
                paint.drawLine(
                    plot.m_lineColor,
                    plot.m_lineWidth,
                    0,
                    mpx1,
                    mpy1,
                    rightX.toInt(),
                    rightY.toInt()
                )
                mpy1 = getChartY(0, plot.m_value1 - m_downSubValue)
                mpy2 = getChartY(0, plot.m_value2 - m_downSubValue)
                lineXY(mpx1.toDouble(), mpy1.toDouble(), mpx2.toDouble(), mpy2.toDouble(), 0.0, 0.0)
                rightY = rightX * m_kChart + m_bChart
                paint.drawLine(
                    plot.m_lineColor,
                    plot.m_lineWidth,
                    0,
                    mpx1,
                    mpy1,
                    rightX.toInt(),
                    rightY.toInt()
                )
            } else if (plot.m_plotType == "Segment") {
                paint.drawLine(plot.m_lineColor, plot.m_lineWidth, 0, mpx1, mpy1, mpx2, mpy2)
            } else if (plot.m_plotType == "Ray") {
                lineXY(mpx1.toDouble(), mpy1.toDouble(), mpx2.toDouble(), mpy2.toDouble(), 0.0, 0.0)
                if (m_kChart != 0.0 || m_bChart != 0.0) {
                    val leftX = m_leftVScaleWidth.toDouble()
                    val leftY = leftX * m_kChart + m_bChart
                    val rightX = (size.cx - m_rightVScaleWidth).toDouble()
                    val rightY = rightX * m_kChart + m_bChart
                    if (mpx1 >= mpx2) {
                        paint.drawLine(
                            plot.m_lineColor,
                            plot.m_lineWidth,
                            0,
                            leftX.toInt(),
                            leftY.toInt(),
                            mpx1,
                            mpy1
                        )
                    } else {
                        paint.drawLine(
                            plot.m_lineColor,
                            plot.m_lineWidth,
                            0,
                            mpx1,
                            mpy1,
                            rightX.toInt(),
                            rightY.toInt()
                        )
                    }
                } else {
                    if (mpy1 >= mpy2) {
                        paint.drawLine(
                            plot.m_lineColor, plot.m_lineWidth, 0, mpx1, mpy1, mpx1, 0
                        )
                    } else {
                        paint.drawLine(
                            plot.m_lineColor, plot.m_lineWidth, 0, mpx1, mpy1, mpx1, divHeight
                        )
                    }
                }
            } else if (plot.m_plotType == "Triangle") {
                paint.drawLine(plot.m_lineColor, plot.m_lineWidth, 0, mpx1, mpy1, mpx2, mpy2)
                paint.drawLine(plot.m_lineColor, plot.m_lineWidth, 0, mpx2, mpy2, mpx3, mpy3)
                paint.drawLine(plot.m_lineColor, plot.m_lineWidth, 0, mpx1, mpy1, mpx3, mpy3)
            } else if (plot.m_plotType == "SymmetricTriangle") {
                if (mpx2 != mpx1) {
                    val a = (mpy2 - mpy1).toDouble() / (mpx2 - mpx1).toDouble()
                    val b = mpy1 - a * mpx1
                    val c = -a
                    val d = mpy3 - c * mpx3
                    val leftX = m_leftVScaleWidth.toDouble()
                    var leftY = leftX * a + b
                    val rightX = (size.cx - m_rightVScaleWidth).toDouble()
                    var rightY = rightX * a + b
                    paint.drawLine(
                        plot.m_lineColor,
                        plot.m_lineWidth,
                        0,
                        leftX.toInt(),
                        leftY.toInt(),
                        rightX.toInt(),
                        rightY.toInt()
                    )
                    leftY = leftX * c + d
                    rightY = rightX * c + d
                    paint.drawLine(
                        plot.m_lineColor,
                        plot.m_lineWidth,
                        0,
                        leftX.toInt(),
                        leftY.toInt(),
                        rightX.toInt(),
                        rightY.toInt()
                    )
                } else {
                    paint.drawLine(
                        plot.m_lineColor, plot.m_lineWidth, 0, mpx1, 0, mpx1, divHeight
                    )
                    paint.drawLine(
                        plot.m_lineColor, plot.m_lineWidth, 0, mpx3, 0, mpx3, divHeight
                    )
                }
            } else if (plot.m_plotType == "Rect") {
                val sX1 = Math.min(mpx1, mpx2)
                val sY1 = Math.min(mpy1, mpy2)
                val sX2 = Math.max(mpx1, mpx2)
                val sY2 = Math.max(mpy1, mpy2)
                paint.drawRect(plot.m_lineColor, plot.m_lineWidth, 0, sX1, sY1, sX2, sY2)
            } else if (plot.m_plotType == "Cycle") {
                val r = Math.sqrt(
                    Math.abs((mpx2 - mpx1) * (mpx2 - mpx1) + (mpy2 - mpy1) * (mpy2 - mpy1))
                        .toDouble()
                ).toInt()
                paint.drawEllipse(
                    plot.m_lineColor, plot.m_lineWidth, 0, mpx1 - r, mpy1 - r,
                    mpx1 + r, mpy1 + r
                )
            } else if (plot.m_plotType == "CircumCycle") {
                ellipseOR(
                    mpx1.toDouble(),
                    mpy1.toDouble(),
                    mpx2.toDouble(),
                    mpy2.toDouble(),
                    mpx3.toDouble(),
                    mpy3.toDouble()
                )
                paint.drawEllipse(
                    plot.m_lineColor,
                    plot.m_lineWidth,
                    0,
                    (m_oXChart - m_rChart).toInt(),
                    (m_oYChart - m_rChart).toInt(),
                    (m_oXChart + m_rChart).toInt(),
                    (m_oYChart + m_rChart).toInt()
                )
            } else if (plot.m_plotType == "Ellipse") {
                var x1 = 0.0
                var y1 = 0.0
                var x2 = 0.0
                var y2 = 0.0
                if (mpx1 <= mpx2) {
                    x1 = mpx2.toDouble()
                    y1 = mpy2.toDouble()
                    x2 = mpx1.toDouble()
                    y2 = mpy1.toDouble()
                } else {
                    x1 = mpx1.toDouble()
                    y1 = mpy1.toDouble()
                    x2 = mpx2.toDouble()
                    y2 = mpy2.toDouble()
                }
                val x = x1 - (x1 - x2)
                var y = 0.0
                val width = (x1 - x2) * 2
                var height = 0.0
                if (y1 >= y2) {
                    height = (y1 - y2) * 2
                } else {
                    height = (y2 - y1) * 2
                }
                y = y2 - height / 2
                paint.drawEllipse(
                    plot.m_lineColor,
                    plot.m_lineWidth,
                    0,
                    x.toInt(),
                    y.toInt(),
                    (x + width).toInt(),
                    (y + height).toInt()
                )
            } else if (plot.m_plotType == "ParalleGram") {
                parallelogram(
                    mpx1.toDouble(),
                    mpy1.toDouble(),
                    mpx2.toDouble(),
                    mpy2.toDouble(),
                    mpx3.toDouble(),
                    mpy3.toDouble()
                )
                paint.drawLine(plot.m_lineColor, plot.m_lineWidth, 0, mpx1, mpy1, mpx2, mpy2)
                paint.drawLine(plot.m_lineColor, plot.m_lineWidth, 0, mpx2, mpy2, mpx3, mpy3)
                paint.drawLine(
                    plot.m_lineColor,
                    plot.m_lineWidth,
                    0,
                    mpx3,
                    mpy3,
                    m_x4Chart.toInt(),
                    m_y4Chart.toInt()
                )
                paint.drawLine(
                    plot.m_lineColor,
                    plot.m_lineWidth,
                    0,
                    m_x4Chart.toInt(),
                    m_y4Chart.toInt(),
                    mpx1,
                    mpy1
                )
            } else if (plot.m_plotType == "BoxLine") {
                val sX1 = Math.min(mpx1, mpx2)
                val sY1 = Math.min(mpy1, mpy2)
                val sX2 = Math.max(mpx1, mpx2)
                val sY2 = Math.max(mpy1, mpy2)
                paint.drawRect(plot.m_lineColor, plot.m_lineWidth, 0, sX1, sY1, sX2, sY2)
                val bText = FCTran.intToStr(Math.abs(index2 - index1) + 1)
                var tSize = paint.textSize(bText, font)
                paint.drawText(
                    FCTran.intToStr(Math.abs(index2 - index1) + 1), textColor,
                    font, FCRect(sX1 + 2, sY1 + 2, sX1 + 2 + tSize.cx, sY1 + 2 + tSize.cy)
                )
                val closeList = ArrayList<Double>()
                for (j in index1..index2) {
                    closeList.add(m_datas!![j].m_close)
                }
                val avgClose = avgValue(closeList)
                val closeY = getChartY(0, avgClose)
                paint.drawLine(
                    plot.m_lineColor, plot.m_lineWidth, 0, sX1, closeY, sX2, closeY
                )
                val drawAvg = FCTran.getValueByDigit(avgClose, m_candleDigit)
                tSize = paint.textSize(drawAvg, font)
                paint.drawText(
                    drawAvg,
                    textColor,
                    font, FCRect(sX1 + 2, closeY - tSize.cy - 2, sX1 + 2 + tSize.cx, closeY - 2)
                )
            } else if (plot.m_plotType == "TironeLevels") {
                val sX1 = Math.min(mpx1, mpx2)
                val sY1 = Math.min(mpy1, mpy2)
                val sX2 = Math.max(mpx1, mpx2)
                val sY2 = Math.max(mpy1, mpy2)
                paint.drawLine(plot.m_lineColor, plot.m_lineWidth, 0, sX1, sY1, sX2, sY1)
                paint.drawLine(plot.m_lineColor, plot.m_lineWidth, 0, sX1, sY2, sX2, sY2)
                paint.drawLine(
                    plot.m_lineColor, plot.m_lineWidth, 0, sX1 + (sX2 - sX1) / 2,
                    sY1, sX1 + (sX2 - sX1) / 2, sY2
                )
                val t2 = m_nHighChart - (m_nHighChart - m_nLowChart) / 3
                val t3 = m_nHighChart - (m_nHighChart - m_nLowChart) / 2
                val t4 = m_nHighChart - 2 * (m_nHighChart - m_nLowChart) / 3
                val tList = ArrayList<Double>()
                tList.add(t2)
                tList.add(t3)
                tList.add(t4)
                for (j in tList.indices) {
                    val y = getChartY(0, tList[j])
                    //画直线
                    paint.drawLine(
                        plot.m_lineColor, plot.m_lineWidth, 0, m_leftVScaleWidth,
                        y, size.cx - m_rightVScaleWidth, y
                    )
                    val str = FCTran.getValueByDigit(tList[j], m_candleDigit)
                    val tSize = paint.textSize(str, font)
                    paint.drawText(
                        str, textColor, font,
                        FCRect(
                            m_leftVScaleWidth + 2,
                            y - tSize.cy - 2,
                            m_leftVScaleWidth + 2 + tSize.cx,
                            y - 2
                        )
                    )
                }
            } else if (plot.m_plotType == "QuadrantLines") {
                val sX1 = Math.min(mpx1, mpx2)
                val sY1 = Math.min(mpy1, mpy2)
                val sX2 = Math.max(mpx1, mpx2)
                val sY2 = Math.max(mpy1, mpy2)
                paint.drawLine(plot.m_lineColor, plot.m_lineWidth, 0, sX1, sY1, sX2, sY1)
                paint.drawLine(plot.m_lineColor, plot.m_lineWidth, 0, sX1, sY2, sX2, sY2)
                val t2 = m_nHighChart - (m_nHighChart - m_nLowChart) / 4
                val t3 = m_nHighChart - (m_nHighChart - m_nLowChart) / 2
                val t4 = m_nHighChart - 3 * (m_nHighChart - m_nLowChart) / 4
                val tList = ArrayList<Double>()
                tList.add(t2)
                tList.add(t3)
                tList.add(t4)
                for (j in tList.indices) {
                    val y = getChartY(0, tList[j])
                    //画直线
                    paint.drawLine(plot.m_lineColor, plot.m_lineWidth, 0, sX1, y, sX2, y)
                }
            } else if (plot.m_plotType == "GoldenRatio") {
                val sY1 = Math.min(mpy1, mpy2).toDouble()
                val sY2 = Math.max(mpy1, mpy2).toDouble()
                val ranges = ArrayList<Double>()
                ranges.add(0.0)
                ranges.add(0.236)
                ranges.add(0.382)
                ranges.add(0.5)
                ranges.add(0.618)
                ranges.add(0.809)
                ranges.add(1.0)
                ranges.add(1.382)
                ranges.add(1.618)
                ranges.add(2.0)
                ranges.add(2.382)
                ranges.add(2.618)
                for (j in ranges.indices) {
                    val newY =
                        if (sY1 <= sY2) sY1 + (sY2 - sY1) * ranges[j] else sY2 + (sY1 - sY2) * (1 - ranges[j])
                    paint.drawLine(
                        plot.m_lineColor,
                        plot.m_lineWidth,
                        0,
                        m_leftVScaleWidth,
                        newY.toInt(),
                        size.cx - m_rightVScaleWidth,
                        newY.toInt()
                    )
                    val newPoint = FCPoint(0, newY.toInt())
                    val value = getCandleDivValue(newPoint)
                    val str = FCTran.getValueByDigit(value, m_candleDigit)
                    val tSize = paint.textSize(str, font)
                    paint.drawText(
                        str, textColor, font,
                        FCRect(
                            m_leftVScaleWidth + 2,
                            newY.toInt() - tSize.cy - 2,
                            m_leftVScaleWidth + 2 + tSize.cx,
                            newY.toInt() - 2
                        )
                    )
                }
            }
        }
        paint.setClip(clipRect)
    }

    /**
     * 绘制图表
     * @params paint 绘图对象
     * @params clipRect 裁剪区
     */
    fun drawChartStock(paint: FCPaint, clipRect: FCRect) {
        val candleHeight = candleDivHeight
        val volHeight = volDivHeight
        val indHeight = indDivHeight
        val indHeight2 = indDivHeight2
        val size = size
        val isTrend = m_cycle == "trend"
        var cWidth = ((m_hScalePixel - 3) / 2).toInt()
        if (cWidth < 0) {
            cWidth = 0
        }
        var lastValidIndex = m_lastVisibleIndex
        if (m_lastValidIndex != -1) {
            lastValidIndex = m_lastValidIndex
        }
        if (m_datas!!.size > 0) {
            val maxVisibleRecord =
                getChartMaxVisibleCount(m_hScalePixel, chartWorkAreaWidth.toDouble())
            paint.setClip(
                FCRect(
                    Math.max(clipRect.left, m_leftVScaleWidth),
                    Math.max(clipRect.top, 0),
                    Math.min(clipRect.right, size.cx - m_rightVScaleWidth),
                    Math.min(clipRect.bottom, candleHeight)
                )
            )
            if (isTrend) {
                val points = arrayOfNulls<FCPoint>(lastValidIndex - m_firstVisibleIndex + 1)
                for (i in m_firstVisibleIndex..lastValidIndex) {
                    val x = getChartX(i)
                    val close = m_datas!![i].m_close
                    val closeY = getChartY(0, close)
                    points[i - m_firstVisibleIndex] = FCPoint(x, closeY)
                }
                paint.drawPolyline(m_trendColor, m_lineWidthChart, 0, points)
            }else {
                var hasMinTag = false
                var hasMaxTag = false
                for (i in m_firstVisibleIndex..lastValidIndex) {
                    val x = getChartX(i)
                    val open = m_datas!![i].m_open
                    val close = m_datas!![i].m_close
                    val high = m_datas!![i].m_high
                    val low = m_datas!![i].m_low
                    val openY = getChartY(0, open)
                    val closeY = getChartY(0, close)
                    val highY = getChartY(0, high)
                    val lowY = getChartY(0, low)
                    if (close >= open) {
                        if (close == open && m_midColor != FCColor.None) {
                            paint.drawLine(
                                m_midColor, m_lineWidthChart, 0, x, highY, x, lowY
                            )
                        } else {
                            paint.drawLine(
                                m_upColor, m_lineWidthChart, 0, x, highY, x, lowY
                            )
                        }
                        if (cWidth > 0) {
                            if (close == open) {
                                if (m_midColor != FCColor.None) {
                                    paint.drawLine(
                                        m_midColor, m_lineWidthChart, 0, x - cWidth,
                                        closeY, x + cWidth, closeY
                                    )
                                } else {
                                    paint.drawLine(
                                        m_upColor, m_lineWidthChart, 0, x - cWidth,
                                        closeY, x + cWidth, closeY
                                    )
                                }
                            } else {
                                if (m_candleStyle == "rect2") {
                                    paint.fillRect(
                                        m_backColor, x - cWidth, closeY, x + cWidth, openY
                                    )
                                    paint.drawRect(
                                        m_upColor,
                                        1f,
                                        0,
                                        x - cWidth,
                                        closeY,
                                        x + cWidth + 1,
                                        openY
                                    )
                                } else {
                                    paint.fillRect(
                                        m_upColor, x - cWidth, closeY, x + cWidth, openY
                                    )
                                }
                            }
                        }
                    } else {
                        paint.drawLine(
                            m_downColor, m_lineWidthChart, 0, x, highY, x, lowY
                        )
                        if (cWidth > 0) {
                            paint.fillRect(
                                m_downColor, x - cWidth, openY, x + cWidth, closeY
                            )
                        }
                    }
                    if (m_selectShape == "CANDLE") {
                        var kPInterval = maxVisibleRecord / 30
                        if (kPInterval < 2) {
                            kPInterval = 3
                        }
                        if (i % kPInterval == 0) {
                            paint.fillRect(
                                m_indicatorColors[0], x - 3, closeY - 3, x + 3, closeY + 3
                            )
                        }
                    }
                    if (!hasMaxTag) {
                        if (high == m_candleMax) {
                            val tag = FCTran.getValueByDigit(high, m_candleDigit)
                            val tSize = paint.textSize(tag, font)
                            paint.drawText(
                                tag, textColor, font, FCRect(
                                    x - tSize.cx / 2,
                                    highY - tSize.cy / 2 - 2,
                                    x + tSize.cx / 2,
                                    highY + tSize.cy / 2 - 2
                                )
                            )
                            hasMaxTag = true
                        }
                    }
                    if (!hasMinTag) {
                        if (low == m_candleMin) {
                            val tag = FCTran.getValueByDigit(low, m_candleDigit)
                            val tSize = paint.textSize(tag, font)
                            paint.drawText(
                                tag, textColor, font, FCRect(
                                    x - tSize.cx / 2,
                                    lowY + 2 + tSize.cy / 2, x + tSize.cx / 2,
                                    lowY + 2 + tSize.cy * 3 / 2
                                )
                            )
                            hasMinTag = true
                        }
                    }
                }
            }
            paint.setClip(clipRect)
            if(volHeight > 0) {
                for (i in m_firstVisibleIndex..lastValidIndex) {
                    val x = getChartX(i)
                    val open = m_datas!![i].m_open
                    val close = m_datas!![i].m_close
                    val volume = m_datas!![i].m_volume
                    var volY = getChartY(1, volume)
                    var zeroY = getChartY(1, 0.0)
                    if (close >= open) {
                        if (isTrend) {
                            paint.drawLine(
                                m_upColor, m_lineWidthChart, 0, x,
                                volY, x, zeroY
                            )
                        } else {
                            if (cWidth > 0) {
                                if (m_barStyle == "rect2") {
                                    paint.fillRect(
                                        m_backColor, x - cWidth, volY, x + cWidth, zeroY
                                    )
                                    paint.drawRect(
                                        m_upColor,
                                        1f,
                                        0,
                                        x - cWidth,
                                        volY,
                                        x + cWidth + 1,
                                        zeroY
                                    )
                                } else {
                                    paint.fillRect(
                                        m_upColor, x - cWidth, volY, x + cWidth, zeroY
                                    )
                                }
                            } else {
                                paint.drawLine(
                                    m_upColor, m_lineWidthChart, 0, x - cWidth,
                                    volY, x + cWidth, zeroY
                                )
                            }
                        }
                    } else {
                        if (isTrend) {
                            paint.drawLine(
                                m_downColor, m_lineWidthChart, 0, x,
                                volY, x, zeroY
                            )
                        } else {
                            if (cWidth > 0) {
                                paint.fillRect(
                                    m_downColor, x - cWidth, volY, x + cWidth, zeroY
                                )
                            } else {
                                paint.drawLine(
                                    m_downColor, m_lineWidthChart, 0,
                                    x - cWidth, volY, x + cWidth, zeroY
                                )
                            }
                        }
                    }
                    if (m_selectShape == "VOL") {
                        var kPInterval = maxVisibleRecord / 30
                        if (kPInterval < 2) {
                            kPInterval = 3
                        }
                        if (i % kPInterval == 0) {
                            paint.fillRect(
                                m_indicatorColors[0], x - 3, volY - 3, x + 3, volY + 3
                            )
                        }
                    }
                }
            }
            if (!isTrend) {
                paint.setClip(
                    FCRect(
                        Math.max(clipRect.left, m_leftVScaleWidth),
                        Math.max(clipRect.top, 0),
                        Math.min(clipRect.right, size.cx - m_rightVScaleWidth),
                        Math.min(clipRect.bottom, candleHeight)
                    )
                )
                if (m_mainIndicator == "BOLL") {
                    drawChartLines(
                        paint, clipRect, 0,
                        m_bollMid, m_indicatorColors[0],
                        if (m_selectShape == m_mainIndicator && m_selectShapeEx == "MID") true else false
                    )
                    drawChartLines(
                        paint, clipRect, 0,
                        m_bollUp, m_indicatorColors[1],
                        if (m_selectShape == m_mainIndicator && m_selectShapeEx == "UP") true else false
                    )
                    drawChartLines(
                        paint, clipRect, 0,
                        m_bollDown, m_indicatorColors[2],
                        if (m_selectShape == m_mainIndicator && m_selectShapeEx == "DOWN") true else false
                    )
                } else if (m_mainIndicator == "MA") {
                    drawChartLines(
                        paint, clipRect, 0,
                        m_ma5, m_indicatorColors[0],
                        if (m_selectShape == m_mainIndicator && m_selectShapeEx == "5") true else false
                    )
                    drawChartLines(
                        paint, clipRect, 0,
                        m_ma10, m_indicatorColors[0],
                        if (m_selectShape == m_mainIndicator && m_selectShapeEx == "10") true else false
                    )
                    drawChartLines(
                        paint, clipRect, 0,
                        m_ma20, m_indicatorColors[2],
                        if (m_selectShape == m_mainIndicator && m_selectShapeEx == "20") true else false
                    )
                    drawChartLines(
                        paint, clipRect, 0,
                        m_ma30, m_indicatorColors[5],
                        if (m_selectShape == m_mainIndicator && m_selectShapeEx == "30") true else false
                    )
                    drawChartLines(
                        paint, clipRect, 0,
                        m_ma120, m_indicatorColors[4],
                        if (m_selectShape == m_mainIndicator && m_selectShapeEx == "120") true else false
                    )
                    drawChartLines(
                        paint, clipRect, 0,
                        m_ma250, m_indicatorColors[3],
                        if (m_selectShape == m_mainIndicator && m_selectShapeEx == "250") true else false
                    )
                }
                paint.setClip(clipRect)
            }
            if (indHeight > 0 || indHeight2 > 0) {
                for (d in 2..3) {
                    var sind = m_showIndicator
                    if (d == 3) {
                        sind = m_showIndicator2
                        if (indHeight2 <= 0) {
                            continue
                        }
                    } else {
                        if (indHeight <= 0) {
                            continue
                        }
                    }
                    if (sind == "MACD") {
                        val zeroY = getChartY(d, 0.0)
                        paint.drawLine(
                            m_indicatorColors[4], m_lineWidthChart, 0,
                            m_leftVScaleWidth, zeroY, getChartX(m_lastVisibleIndex), zeroY
                        )
                        for (i in m_firstVisibleIndex..lastValidIndex) {
                            val x = getChartX(i)
                            val macd = m_allmacdarr[i]
                            val macdY = getChartY(d, macd)
                            if (macdY < zeroY) {
                                paint.drawLine(
                                    m_indicatorColors[3], m_lineWidthChart, 0, x,
                                    macdY, x, zeroY
                                )
                            } else {
                                paint.drawLine(
                                    m_indicatorColors[4], m_lineWidthChart, 0, x,
                                    macdY, x, zeroY
                                )
                            }
                            if (m_selectShape == sind && m_selectShapeEx == "MACD") {
                                var kPInterval = maxVisibleRecord / 30
                                if (kPInterval < 2) {
                                    kPInterval = 3
                                }
                                if (i % kPInterval == 0) {
                                    paint.fillRect(
                                        m_indicatorColors[4], x - 3, macdY - 3, x + 3, macdY + 3
                                    )
                                }
                            }
                        }
                        drawChartLines(
                            paint, clipRect, d,
                            m_alldifarr, m_indicatorColors[0],
                            if (m_selectShape == sind && m_selectShapeEx == "DIF") true else false
                        )
                        drawChartLines(
                            paint, clipRect, d,
                            m_alldeaarr, m_indicatorColors[0],
                            if (m_selectShape == sind && m_selectShapeEx == "DEA") true else false
                        )
                    } else if (sind == "KDJ") {
                        drawChartLines(
                            paint, clipRect, d,
                            m_kdjK, m_indicatorColors[0],
                            if (m_selectShape == sind && m_selectShapeEx == "K") true else false
                        )
                        drawChartLines(
                            paint, clipRect, d,
                            m_kdjD, m_indicatorColors[1],
                            if (m_selectShape == sind && m_selectShapeEx == "D") true else false
                        )
                        drawChartLines(
                            paint, clipRect, d,
                            m_kdjJ, m_indicatorColors[2],
                            if (m_selectShape == sind && m_selectShapeEx == "J") true else false
                        )
                    } else if (sind == "RSI") {
                        drawChartLines(
                            paint, clipRect, d,
                            m_rsi1, m_indicatorColors[5],
                            if (m_selectShape == sind && m_selectShapeEx == "6") true else false
                        )
                        drawChartLines(
                            paint, clipRect, d,
                            m_rsi2, m_indicatorColors[1],
                            if (m_selectShape == sind && m_selectShapeEx == "12") true else false
                        )
                        drawChartLines(
                            paint, clipRect, d,
                            m_rsi3, m_indicatorColors[2],
                            if (m_selectShape == sind && m_selectShapeEx == "24") true else false
                        )
                    } else if (sind == "BIAS") {
                        drawChartLines(
                            paint, clipRect, d,
                            m_bias1, m_indicatorColors[5],
                            if (m_selectShape == sind && m_selectShapeEx == "1") true else false
                        )
                        drawChartLines(
                            paint, clipRect, d,
                            m_bias2, m_indicatorColors[1],
                            if (m_selectShape == sind && m_selectShapeEx == "2") true else false
                        )
                        drawChartLines(
                            paint, clipRect, d, m_bias3,
                            m_indicatorColors[2],
                            if (m_selectShape == sind && m_selectShapeEx == "3") true else false
                        )
                    } else if (sind == "ROC") {
                        drawChartLines(
                            paint, clipRect, d,
                            m_roc, m_indicatorColors[0],
                            if (m_selectShape == sind && m_selectShapeEx == "ROC") true else false
                        )
                        drawChartLines(
                            paint, clipRect, d,
                            m_rocMa, m_indicatorColors[1],
                            if (m_selectShape == sind && m_selectShapeEx == "ROCMA") true else false
                        )
                    } else if (sind == "WR") {
                        drawChartLines(
                            paint, clipRect, d,
                            m_wr1, m_indicatorColors[0],
                            if (m_selectShape == sind && m_selectShapeEx == "1") true else false
                        )
                        drawChartLines(
                            paint, clipRect, d,
                            m_wr2, m_indicatorColors[1],
                            if (m_selectShape == sind && m_selectShapeEx == "2") true else false
                        )
                    } else if (sind == "CCI") {
                        drawChartLines(
                            paint, clipRect, d,
                            m_cci, m_indicatorColors[0],
                            if (m_selectShape == sind) true else false
                        )
                    } else if (sind == "BBI") {
                        drawChartLines(
                            paint, clipRect, d,
                            m_bbi, m_indicatorColors[0],
                            if (m_selectShape == sind) true else false
                        )
                    } else if (sind == "TRIX") {
                        drawChartLines(
                            paint, clipRect, d,
                            m_trix, m_indicatorColors[0],
                            if (m_selectShape == sind && m_selectShapeEx == "TRIX") true else false
                        )
                        drawChartLines(
                            paint, clipRect, d,
                            m_trixMa, m_indicatorColors[1],
                            if (m_selectShape == sind && m_selectShapeEx == "TRIXMA") true else false
                        )
                    } else if (sind == "DMA") {
                        drawChartLines(
                            paint, clipRect, d, m_dma1, m_indicatorColors[0],
                            if (m_selectShape == sind && m_selectShapeEx === "DIF") true else false
                        )
                        drawChartLines(
                            paint, clipRect, d, m_dma2, m_indicatorColors[1],
                            if (m_selectShape == sind && m_selectShapeEx === "DIFMA") true else false
                        )
                    }
                }
            }
        }
        //绘制扩展线条
        if (m_shapes.size > 0) {
            for (i in m_shapes.indices) {
                val shape = m_shapes[i]
                if (shape.m_shapeType == "bar") {
                    for (j in m_firstVisibleIndex..lastValidIndex) {
                        if (shape.m_showHideDatas.size > j && shape.m_showHideDatas[j].toString() == "0") {
                            continue
                        }
                        val x = getChartX(j)
                        var y1 = 0
                        if (shape.m_leftOrRight) {
                            y1 = getChartY(shape.m_divIndex, shape.m_datas[j])
                        } else {
                            y1 = getChartYInRight(shape.m_divIndex, shape.m_datas[j])
                        }
                        if (shape.m_style != "2color") {
                            var y2 = 0
                            if (shape.m_leftOrRight) {
                                y2 = getChartY(shape.m_divIndex, shape.m_datas2[j])
                            } else {
                                y2 = getChartYInRight(shape.m_divIndex, shape.m_datas2[j])
                            }
                            if (y1 >= y2) {
                                paint.fillRect(shape.m_color, x - cWidth, y2, x + cWidth, y1)
                            } else {
                                paint.fillRect(shape.m_color, x - cWidth, y1, x + cWidth, y2)
                            }
                        } else {
                            var y2 = 0
                            if (shape.m_leftOrRight) {
                                y2 = getChartY(shape.m_divIndex, 0.0)
                            } else {
                                y2 = getChartYInRight(shape.m_divIndex, 0.0)
                            }
                            if (y1 >= y2) {
                                paint.drawLine(shape.m_color2, 1f, 0, x, y1, x, y2)
                            } else {
                                paint.drawLine(shape.m_color, 1f, 0, x, y1, x, y2)
                            }
                            if (j == lastValidIndex) {
                                paint.drawLine(
                                    shape.m_color2, 1f, 0, m_leftVScaleWidth, y2,
                                    size.cx - m_rightVScaleWidth, y2
                                )
                            }
                        }
                    }
                } else if (shape.m_shapeType == "text") {
                    for (j in m_firstVisibleIndex..lastValidIndex) {
                        val x = getChartX(j)
                        if (shape.m_datas[j] != 0.0) {
                            var y1 = 0
                            if (shape.m_leftOrRight) {
                                y1 = getChartY(shape.m_divIndex, shape.m_value)
                            } else {
                                y1 = getChartYInRight(shape.m_divIndex, shape.m_value)
                            }
                            val drawText = shape.m_text
                            val tSize = paint.textSize(drawText, font)
                            paint.drawText(
                                drawText, shape.m_color, font,
                                FCRect(
                                    x - tSize.cx / 2,
                                    y1 - tSize.cy / 2,
                                    x + tSize.cx / 2,
                                    y1 + tSize.cy / 2
                                )
                            )
                        }
                    }
                } else {
                    if (shape.m_leftOrRight) {
                        drawChartLines(
                            paint, clipRect, shape.m_divIndex,
                            shape.m_datas, shape.m_color,
                            if (m_selectShape == shape.m_shapeName) true else false
                        )
                    } else {
                        drawChartLinesInRight(
                            paint, clipRect, shape.m_divIndex,
                            shape.m_datas, shape.m_color,
                            if (m_selectShape == shape.m_shapeName) true else false
                        )
                    }
                }
            }
        }
    }

    /**
     * 绘制十字线
     * @params paint 绘图对象
     * @params clipRect 裁剪区
     */
    open fun drawChartCrossLine(paint: FCPaint, clipRect: FCRect?) {
        if (m_datas == null || m_datas!!.size == 0) {
            return
        }
        val size = size
        val candleDivHeight = candleDivHeight
        val volDivHeight = volDivHeight
        val indDivHeight = indDivHeight
        val indDivHeight2 = indDivHeight2
        var crossLineIndex = m_crossStopIndex
        if (crossLineIndex == -1 || !m_showCrossLine) {
            if (m_lastValidIndex != -1) {
                crossLineIndex = m_lastValidIndex
            } else {
                crossLineIndex = m_lastVisibleIndex
            }
        }
        if (crossLineIndex == -1) {
            return
        }
        if (volDivHeight > 0) {
            val drawTitles = ArrayList<String>()
            val drawColors = ArrayList<Long>()
            drawTitles.add(
                "VOL ".toString() +
                        FCTran.getValueByDigit(
                            m_datas!![crossLineIndex].m_volume / m_magnitude,
                            m_volDigit
                        )
            )
            drawColors.add(textColor)
            if (m_shapes.size > 0) {
                for (i in m_shapes.indices) {
                    val shape = m_shapes[i]
                    if (shape.m_divIndex == 1) {
                        if (shape.m_title.length > 0) {
                            if (shape.m_shapeType == "bar" && shape.m_style == "2color") {
                                drawTitles.add(
                                    shape.m_title +
                                            " ".toString() +
                                            FCTran.getValueByDigit(
                                                shape.m_datas[crossLineIndex],
                                                m_volDigit
                                            )
                                )
                                drawColors.add(shape.m_color2)
                            } else {
                                if (shape.m_shapeType != "text") {
                                    drawTitles.add(
                                        (shape.m_title +
                                                " ".toString() +
                                                FCTran.getValueByDigit(
                                                    shape.m_datas[crossLineIndex],
                                                    m_volDigit
                                                ))
                                    )
                                    drawColors.add(shape.m_color)
                                    if (shape.m_datas2.size > 0) {
                                        drawTitles.add(
                                            (shape.m_title2 +
                                                    " ".toString() +
                                                    FCTran.getValueByDigit(
                                                        shape.m_datas2[crossLineIndex],
                                                        m_volDigit
                                                    ))
                                        )
                                        drawColors.add(shape.m_color2)
                                    }
                                }
                            }
                        }
                    }
                }
            }
            var iLeft = m_leftVScaleWidth + 5
            for (i in drawTitles.indices) {
                val tSize = paint.textSize(drawTitles[i], font)
                paint.drawText(
                    drawTitles[i],
                    drawColors[i],
                    font,
                    FCRect(
                        iLeft,
                        candleDivHeight + 5,
                        iLeft + tSize.cx,
                        candleDivHeight + 5 + tSize.cy
                    )
                )
                iLeft += tSize.cx + 5
            }
        }
        //上面显示数据  高开低收
        if ((m_cycle == "trend")) {
            val drawTitles = ArrayList<String>()
            val drawColors = ArrayList<Long>()
            if (m_text.length > 0) {
                drawTitles.add(m_text)
                drawColors.add(textColor)
            }
            if (m_shapes.size > 0) {
                for (i in m_shapes.indices) {
                    val shape = m_shapes[i]
                    if (shape.m_divIndex == 0) {
                        if (shape.m_title.length > 0) {
                            if ((shape.m_shapeType == "bar") && (shape.m_style == "2color")) {
                                drawTitles.add(
                                    (shape.m_title +
                                            " ".toString() +
                                            FCTran.getValueByDigit(
                                                shape.m_datas[crossLineIndex],
                                                m_candleDigit
                                            ))
                                )
                                drawColors.add(shape.m_color2)
                            } else {
                                if (shape.m_shapeType != "text") {
                                    drawTitles.add(
                                        (shape.m_title +
                                                " ".toString() +
                                                FCTran.getValueByDigit(
                                                    shape.m_datas[crossLineIndex],
                                                    m_candleDigit
                                                ))
                                    )
                                    drawColors.add(shape.m_color)
                                    if (shape.m_datas2.size > 0) {
                                        drawTitles.add(
                                            (shape.m_title2 +
                                                    " ".toString() +
                                                    FCTran.getValueByDigit(
                                                        shape.m_datas2[crossLineIndex],
                                                        m_candleDigit
                                                    ))
                                        )
                                        drawColors.add(shape.m_color2)
                                    }
                                }
                            }
                        }
                    }
                }
            }
            var iLeft = m_leftVScaleWidth + 5
            for (i in drawTitles.indices) {
                val tSize = paint.textSize(drawTitles[i], font)
                paint.drawText(
                    drawTitles[i], drawColors[i],
                    font, FCRect(iLeft, 5, iLeft + tSize.cx, 5 + tSize.cy)
                )
                iLeft += tSize.cx + 5
            }
        } else {
            val drawTitles = ArrayList<String>()
            val drawColors = ArrayList<Long>()
            if (m_text.length > 0) {
                drawTitles.add(m_text)
                drawColors.add(textColor)
            }
            if ((m_mainIndicator == "MA")) {
                if (m_ma5.size > 0) {
                    drawTitles.add(
                        "MA5 ".toString() +
                                FCTran.getValueByDigit(m_ma5[crossLineIndex], m_candleDigit)
                    )
                } else {
                    drawTitles.add("MA5")
                }
                drawColors.add(m_indicatorColors[0])
                if (m_ma10.size > 0) {
                    drawTitles.add(
                        "MA10 ".toString() +
                                FCTran.getValueByDigit(m_ma10[crossLineIndex], m_candleDigit)
                    )
                } else {
                    drawTitles.add("MA10")
                }
                drawColors.add(m_indicatorColors[1])
                if (m_ma20.size > 0) {
                    drawTitles.add(
                        "MA20 ".toString() +
                                FCTran.getValueByDigit(m_ma20[crossLineIndex], m_candleDigit)
                    )
                } else {
                    drawTitles.add("MA20")
                }
                drawColors.add(m_indicatorColors[2])
                if (m_ma30.size > 0) {
                    drawTitles.add(
                        "MA30 ".toString() +
                                FCTran.getValueByDigit(m_ma30[crossLineIndex], m_candleDigit)
                    )
                } else {
                    drawTitles.add("MA30")
                }
                drawColors.add(m_indicatorColors[5])
                if (m_ma120.size > 0) {
                    drawTitles.add(
                        "MA120 ".toString() +
                                FCTran.getValueByDigit(m_ma120[crossLineIndex], m_candleDigit)
                    )
                } else {
                    drawTitles.add("MA120")
                }
                drawColors.add(m_indicatorColors[4])
                if (m_ma250.size > 0) {
                    drawTitles.add(
                        "MA250 ".toString() +
                                FCTran.getValueByDigit(m_ma250[crossLineIndex], m_candleDigit)
                    )
                } else {
                    drawTitles.add("MA250")
                }
                drawColors.add(m_indicatorColors[3])
            } else if ((m_mainIndicator == "BOLL")) {
                if (m_bollMid.size > 0) {
                    drawTitles.add(
                        "MID ".toString() +
                                FCTran.getValueByDigit(m_bollMid[crossLineIndex], m_candleDigit)
                    )
                } else {
                    drawTitles.add("MID")
                }
                drawColors.add(m_indicatorColors[0])
                if (m_bollUp.size > 0) {
                    drawTitles.add(
                        "UP ".toString() +
                                FCTran.getValueByDigit(m_bollUp[crossLineIndex], m_candleDigit)
                    )
                } else {
                    drawTitles.add("UP")
                }
                drawColors.add(m_indicatorColors[1])
                if (m_bollDown.size > 0) {
                    drawTitles.add(
                        "LOW ".toString() +
                                FCTran.getValueByDigit(m_bollDown[crossLineIndex], m_candleDigit)
                    )
                } else {
                    drawTitles.add("LOW")
                }
                drawColors.add(m_indicatorColors[2])
            }
            if (m_shapes.size > 0) {
                for (i in m_shapes.indices) {
                    val shape = m_shapes[i]
                    if (shape.m_divIndex == 0) {
                        if (shape.m_title.length > 0) {
                            if ((shape.m_shapeType == "bar") && (shape.m_style == "2color")) {
                                drawTitles.add(
                                    (shape.m_title +
                                            " ".toString() +
                                            FCTran.getValueByDigit(
                                                shape.m_datas[crossLineIndex],
                                                m_candleDigit
                                            ))
                                )
                                drawColors.add(shape.m_color2)
                            } else {
                                if (shape.m_shapeType != "text") {
                                    drawTitles.add(
                                        (shape.m_title +
                                                " ".toString() +
                                                FCTran.getValueByDigit(
                                                    shape.m_datas[crossLineIndex], m_candleDigit
                                                ))
                                    )
                                    drawColors.add(shape.m_color)
                                    if (shape.m_datas2.size > 0) {
                                        drawTitles.add(
                                            (shape.m_title2 +
                                                    " ".toString() +
                                                    FCTran.getValueByDigit(
                                                        shape.m_datas2[crossLineIndex],
                                                        m_candleDigit
                                                    ))
                                        )
                                        drawColors.add(shape.m_color2)
                                    }
                                }
                            }
                        }
                    }
                }
            }
            var iLeft = m_leftVScaleWidth + 5
            for (i in drawTitles.indices) {
                val tSize = paint.textSize(drawTitles[i], font)
                paint.drawText(
                    drawTitles[i], drawColors[i],
                    font, FCRect(iLeft, 5, iLeft + tSize.cx, 5 + tSize.cy)
                )
                iLeft += tSize.cx + 5
            }
        }
        if (indDivHeight > 0) {
            val drawTitles = ArrayList<String>()
            val drawColors = ArrayList<Long>()
            if ((m_showIndicator == "MACD")) {
                if (m_alldifarr.size > 0) {
                    drawTitles.add(
                        "DIF ".toString() +
                                FCTran.getValueByDigit(m_alldifarr[crossLineIndex], m_indDigit)
                    )
                } else {
                    drawTitles.add("DIF")
                }
                drawColors.add(m_indicatorColors[0])
                if (m_alldeaarr.size > 0) {
                    drawTitles.add(
                        "DEA ".toString() +
                                FCTran.getValueByDigit(m_alldeaarr[crossLineIndex], m_indDigit)
                    )
                } else {
                    drawTitles.add("DEA")
                }
                drawColors.add(m_indicatorColors[1])
                if (m_allmacdarr.size > 0) {
                    drawTitles.add(
                        "MACD ".toString() +
                                FCTran.getValueByDigit(m_allmacdarr[crossLineIndex], m_indDigit)
                    )
                } else {
                    drawTitles.add("MACD")
                }
                drawColors.add(m_indicatorColors[4])
            } else if ((m_showIndicator == "KDJ")) {
                if (m_kdjK.size > 0) {
                    drawTitles.add(
                        "K ".toString() +
                                FCTran.getValueByDigit(m_kdjK[crossLineIndex], m_indDigit)
                    )
                } else {
                    drawTitles.add("K")
                }
                drawColors.add(m_indicatorColors[0])
                if (m_kdjD.size > 0) {
                    drawTitles.add(
                        "D ".toString() +
                                FCTran.getValueByDigit(m_kdjD[crossLineIndex], m_indDigit)
                    )
                } else {
                    drawTitles.add("D")
                }
                drawColors.add(m_indicatorColors[1])
                if (m_kdjJ.size > 0) {
                    drawTitles.add(
                        "J ".toString() +
                                FCTran.getValueByDigit(m_kdjJ[crossLineIndex], m_indDigit)
                    )
                } else {
                    drawTitles.add("J")
                }
                drawColors.add(m_indicatorColors[2])
            } else if ((m_showIndicator == "RSI")) {
                if (m_rsi1.size > 0) {
                    drawTitles.add(
                        "RSI6 ".toString() +
                                FCTran.getValueByDigit(m_rsi1[crossLineIndex], m_indDigit)
                    )
                } else {
                    drawTitles.add("RSI6")
                }
                drawColors.add(m_indicatorColors[5])
                if (m_rsi2.size > 0) {
                    drawTitles.add(
                        "RSI12 ".toString() +
                                FCTran.getValueByDigit(m_rsi2[crossLineIndex], m_indDigit)
                    )
                } else {
                    drawTitles.add("RSI12")
                }
                drawColors.add(m_indicatorColors[1])
                if (m_rsi3.size > 0) {
                    drawTitles.add(
                        "RSI24 ".toString() +
                                FCTran.getValueByDigit(m_rsi3[crossLineIndex], m_indDigit)
                    )
                } else {
                    drawTitles.add("RSI24")
                }
                drawColors.add(m_indicatorColors[2])
            } else if ((m_showIndicator == "BIAS")) {
                if (m_bias1.size > 0) {
                    drawTitles.add(
                        "BIAS6 ".toString() +
                                FCTran.getValueByDigit(m_bias1[crossLineIndex], m_indDigit)
                    )
                } else {
                    drawTitles.add("BIAS6")
                }
                drawColors.add(m_indicatorColors[5])
                if (m_bias2.size > 0) {
                    drawTitles.add(
                        "BIAS12 ".toString() +
                                FCTran.getValueByDigit(m_bias2[crossLineIndex], m_indDigit)
                    )
                } else {
                    drawTitles.add("BIAS12")
                }
                drawColors.add(m_indicatorColors[1])
                if (m_bias3.size > 0) {
                    drawTitles.add(
                        "BIAS24 ".toString() +
                                FCTran.getValueByDigit(m_bias3[crossLineIndex], m_indDigit)
                    )
                } else {
                    drawTitles.add("BIAS24")
                }
                drawColors.add(m_indicatorColors[2])
            } else if ((m_showIndicator == "ROC")) {
                if (m_roc.size > 0) {
                    drawTitles.add(
                        "ROC ".toString() +
                                FCTran.getValueByDigit(m_roc[crossLineIndex], m_indDigit)
                    )
                } else {
                    drawTitles.add("ROC")
                }
                drawColors.add(m_indicatorColors[0])
                if (m_rocMa.size > 0) {
                    drawTitles.add(
                        "ROCMA ".toString() +
                                FCTran.getValueByDigit(m_rocMa[crossLineIndex], m_indDigit)
                    )
                } else {
                    drawTitles.add("ROCMA")
                }
                drawColors.add(m_indicatorColors[1])
            } else if ((m_showIndicator == "WR")) {
                if (m_wr1.size > 0) {
                    drawTitles.add(
                        "WR5 ".toString() +
                                FCTran.getValueByDigit(m_wr1[crossLineIndex], m_indDigit)
                    )
                } else {
                    drawTitles.add("WR5")
                }
                drawColors.add(m_indicatorColors[0])
                if (m_wr2.size > 0) {
                    drawTitles.add(
                        "WR10 ".toString() +
                                FCTran.getValueByDigit(m_wr2[crossLineIndex], m_indDigit)
                    )
                } else {
                    drawTitles.add("WR10")
                }
                drawColors.add(m_indicatorColors[1])
            } else if ((m_showIndicator == "CCI")) {
                if (m_cci.size > 0) {
                    drawTitles.add(
                        "CCI ".toString() +
                                FCTran.getValueByDigit(m_cci[crossLineIndex], m_indDigit)
                    )
                } else {
                    drawTitles.add("CCI")
                }
                drawColors.add(m_indicatorColors[0])
            } else if ((m_showIndicator == "BBI")) {
                if (m_bbi.size > 0) {
                    drawTitles.add(
                        "BBI ".toString() +
                                FCTran.getValueByDigit(m_bbi[crossLineIndex], m_indDigit)
                    )
                } else {
                    drawTitles.add("BBI")
                }
                drawColors.add(m_indicatorColors[0])
            } else if ((m_showIndicator == "TRIX")) {
                if (m_trix.size > 0) {
                    drawTitles.add(
                        "TRIX ".toString() +
                                FCTran.getValueByDigit(m_trix[crossLineIndex], m_indDigit)
                    )
                } else {
                    drawTitles.add("TRIX")
                }
                drawColors.add(m_indicatorColors[0])
                if (m_trixMa.size > 0) {
                    drawTitles.add(
                        "TRIXMA ".toString() +
                                FCTran.getValueByDigit(m_trixMa[crossLineIndex], m_indDigit)
                    )
                } else {
                    drawTitles.add("TRIXMA")
                }
                drawColors.add(m_indicatorColors[1])
            } else if ((m_showIndicator == "DMA")) {
                if (m_dma1.size > 0) {
                    drawTitles.add(
                        "MA10 ".toString() +
                                FCTran.getValueByDigit(m_dma1[crossLineIndex], m_indDigit)
                    )
                } else {
                    drawTitles.add("MA10")
                }
                drawColors.add(m_indicatorColors[0])
                if (m_dma2.size > 0) {
                    drawTitles.add(
                        "MA50 ".toString() +
                                FCTran.getValueByDigit(m_dma2[crossLineIndex], m_indDigit)
                    )
                } else {
                    drawTitles.add("MA50")
                }
                drawColors.add(m_indicatorColors[1])
            }
            if (m_shapes.size > 0) {
                for (i in m_shapes.indices) {
                    val shape = m_shapes[i]
                    if (shape.m_divIndex == 2) {
                        if (shape.m_title.length > 0) {
                            if ((shape.m_shapeType == "bar") && (shape.m_style == "2color")) {
                                drawTitles.add(
                                    (shape.m_title +
                                            " ".toString() +
                                            FCTran.getValueByDigit(
                                                shape.m_datas[crossLineIndex],
                                                m_indDigit
                                            ))
                                )
                                drawColors.add(shape.m_color2)
                            } else {
                                if (shape.m_shapeType != "text") {
                                    drawTitles.add(
                                        (shape.m_title +
                                                " ".toString() +
                                                FCTran.getValueByDigit(
                                                    shape.m_datas[crossLineIndex], m_indDigit
                                                ))
                                    )
                                    drawColors.add(shape.m_color)
                                    if (shape.m_datas2.size > 0) {
                                        drawTitles.add(
                                            (shape.m_title2 +
                                                    " ".toString() +
                                                    FCTran.getValueByDigit(
                                                        shape.m_datas2[crossLineIndex], m_indDigit
                                                    ))
                                        )
                                        drawColors.add(shape.m_color2)
                                    }
                                }
                            }
                        }
                    }
                }
            }
            var iLeft = m_leftVScaleWidth + 5
            for (i in drawTitles.indices) {
                val tSize = paint.textSize(drawTitles[i], font)
                paint.drawText(
                    drawTitles[i], drawColors[i], font, FCRect(
                        iLeft,
                        candleDivHeight + volDivHeight + 5, iLeft + tSize.cx,
                        candleDivHeight + volDivHeight + 5 + tSize.cy
                    )
                )
                iLeft += tSize.cx + 5
            }
        }
        if (indDivHeight2 > 0) {
            val drawTitles = ArrayList<String>()
            val drawColors = ArrayList<Long>()
            if ((m_showIndicator2 == "MACD")) {
                if (m_alldifarr.size > 0) {
                    drawTitles.add(
                        "DIF ".toString() +
                                FCTran.getValueByDigit(m_alldifarr[crossLineIndex], m_indDigit)
                    )
                } else {
                    drawTitles.add("DIF")
                }
                drawColors.add(m_indicatorColors[0])
                if (m_alldeaarr.size > 0) {
                    drawTitles.add(
                        "DEA ".toString() +
                                FCTran.getValueByDigit(m_alldeaarr[crossLineIndex], m_indDigit)
                    )
                } else {
                    drawTitles.add("DEA")
                }
                drawColors.add(m_indicatorColors[1])
                if (m_allmacdarr.size > 0) {
                    drawTitles.add(
                        "MACD ".toString() +
                                FCTran.getValueByDigit(m_allmacdarr[crossLineIndex], m_indDigit)
                    )
                } else {
                    drawTitles.add("MACD")
                }
                drawColors.add(m_indicatorColors[4])
            } else if ((m_showIndicator2 == "KDJ")) {
                if (m_kdjK.size > 0) {
                    drawTitles.add(
                        "K ".toString() +
                                FCTran.getValueByDigit(m_kdjK[crossLineIndex], m_indDigit)
                    )
                } else {
                    drawTitles.add("K")
                }
                drawColors.add(m_indicatorColors[0])
                if (m_kdjD.size > 0) {
                    drawTitles.add(
                        "D ".toString() +
                                FCTran.getValueByDigit(m_kdjD[crossLineIndex], m_indDigit)
                    )
                } else {
                    drawTitles.add("D")
                }
                drawColors.add(m_indicatorColors[1])
                if (m_kdjJ.size > 0) {
                    drawTitles.add(
                        "J ".toString() +
                                FCTran.getValueByDigit(m_kdjJ[crossLineIndex], m_indDigit)
                    )
                } else {
                    drawTitles.add("J")
                }
                drawColors.add(m_indicatorColors[2])
            } else if ((m_showIndicator2 == "RSI")) {
                if (m_rsi1.size > 0) {
                    drawTitles.add(
                        "RSI6 ".toString() +
                                FCTran.getValueByDigit(m_rsi1[crossLineIndex], m_indDigit)
                    )
                } else {
                    drawTitles.add("RSI6")
                }
                drawColors.add(m_indicatorColors[5])
                if (m_rsi2.size > 0) {
                    drawTitles.add(
                        "RSI12 ".toString() +
                                FCTran.getValueByDigit(m_rsi2[crossLineIndex], m_indDigit)
                    )
                } else {
                    drawTitles.add("RSI12")
                }
                drawColors.add(m_indicatorColors[1])
                if (m_rsi3.size > 0) {
                    drawTitles.add(
                        "RSI24 ".toString() +
                                FCTran.getValueByDigit(m_rsi3[crossLineIndex], m_indDigit)
                    )
                } else {
                    drawTitles.add("RSI24")
                }
                drawColors.add(m_indicatorColors[2])
            } else if ((m_showIndicator2 == "BIAS")) {
                if (m_bias1.size > 0) {
                    drawTitles.add(
                        "BIAS6 ".toString() +
                                FCTran.getValueByDigit(m_bias1[crossLineIndex], m_indDigit)
                    )
                } else {
                    drawTitles.add("BIAS6")
                }
                drawColors.add(m_indicatorColors[5])
                if (m_bias2.size > 0) {
                    drawTitles.add(
                        "BIAS12 ".toString() +
                                FCTran.getValueByDigit(m_bias2[crossLineIndex], m_indDigit)
                    )
                } else {
                    drawTitles.add("BIAS12")
                }
                drawColors.add(m_indicatorColors[1])
                if (m_bias3.size > 0) {
                    drawTitles.add(
                        "BIAS24 ".toString() +
                                FCTran.getValueByDigit(m_bias3[crossLineIndex], m_indDigit)
                    )
                } else {
                    drawTitles.add("BIAS24")
                }
                drawColors.add(m_indicatorColors[2])
            } else if ((m_showIndicator2 == "ROC")) {
                if (m_roc.size > 0) {
                    drawTitles.add(
                        "ROC ".toString() +
                                FCTran.getValueByDigit(m_roc[crossLineIndex], m_indDigit)
                    )
                } else {
                    drawTitles.add("ROC")
                }
                drawColors.add(m_indicatorColors[0])
                if (m_rocMa.size > 0) {
                    drawTitles.add(
                        "ROCMA ".toString() +
                                FCTran.getValueByDigit(m_rocMa[crossLineIndex], m_indDigit)
                    )
                } else {
                    drawTitles.add("ROCMA")
                }
                drawColors.add(m_indicatorColors[1])
            } else if ((m_showIndicator2 == "WR")) {
                if (m_wr1.size > 0) {
                    drawTitles.add(
                        "WR5 ".toString() +
                                FCTran.getValueByDigit(m_wr1[crossLineIndex], m_indDigit)
                    )
                } else {
                    drawTitles.add("WR5")
                }
                drawColors.add(m_indicatorColors[0])
                if (m_wr2.size > 0) {
                    drawTitles.add(
                        "WR10 ".toString() +
                                FCTran.getValueByDigit(m_wr2[crossLineIndex], m_indDigit)
                    )
                } else {
                    drawTitles.add("WR10")
                }
                drawColors.add(m_indicatorColors[1])
            } else if ((m_showIndicator2 == "CCI")) {
                if (m_cci.size > 0) {
                    drawTitles.add(
                        "CCI ".toString() +
                                FCTran.getValueByDigit(m_cci[crossLineIndex], m_indDigit)
                    )
                } else {
                    drawTitles.add("CCI")
                }
                drawColors.add(m_indicatorColors[0])
            } else if ((m_showIndicator2 == "BBI")) {
                if (m_bbi.size > 0) {
                    drawTitles.add(
                        "BBI ".toString() +
                                FCTran.getValueByDigit(m_bbi[crossLineIndex], m_indDigit)
                    )
                } else {
                    drawTitles.add("BBI")
                }
                drawColors.add(m_indicatorColors[0])
            } else if ((m_showIndicator2 == "TRIX")) {
                if (m_trix.size > 0) {
                    drawTitles.add(
                        "TRIX ".toString() +
                                FCTran.getValueByDigit(m_trix[crossLineIndex], m_indDigit)
                    )
                } else {
                    drawTitles.add("TRIX")
                }
                drawColors.add(m_indicatorColors[0])
                if (m_trixMa.size > 0) {
                    drawTitles.add(
                        "TRIXMA ".toString() +
                                FCTran.getValueByDigit(m_trixMa[crossLineIndex], m_indDigit)
                    )
                } else {
                    drawTitles.add("TRIXMA")
                }
                drawColors.add(m_indicatorColors[1])
            } else if ((m_showIndicator2 == "DMA")) {
                if (m_dma1.size > 0) {
                    drawTitles.add(
                        "MA10 ".toString() +
                                FCTran.getValueByDigit(m_dma1[crossLineIndex], m_indDigit)
                    )
                } else {
                    drawTitles.add("MA10")
                }
                drawColors.add(m_indicatorColors[0])
                if (m_dma2.size > 0) {
                    drawTitles.add(
                        "MA50 ".toString() +
                                FCTran.getValueByDigit(m_dma2[crossLineIndex], m_indDigit)
                    )
                } else {
                    drawTitles.add("MA50")
                }
                drawColors.add(m_indicatorColors[1])
            }
            if (m_shapes.size > 0) {
                for (i in m_shapes.indices) {
                    val shape = m_shapes[i]
                    if (shape.m_divIndex == 3) {
                        if (shape.m_title.length > 0) {
                            if ((shape.m_shapeType == "bar") && (shape.m_style == "2color")) {
                                drawTitles.add(
                                    (shape.m_title +
                                            " ".toString() +
                                            FCTran.getValueByDigit(
                                                shape.m_datas[crossLineIndex],
                                                m_indDigit2
                                            ))
                                )
                                drawColors.add(shape.m_color2)
                            } else {
                                if (shape.m_shapeType != "text") {
                                    drawTitles.add(
                                        (shape.m_title +
                                                " ".toString() +
                                                FCTran.getValueByDigit(
                                                    shape.m_datas[crossLineIndex], m_indDigit2
                                                ))
                                    )
                                    drawColors.add(shape.m_color)
                                    if (shape.m_datas2.size > 0) {
                                        drawTitles.add(
                                            (shape.m_title2 +
                                                    " ".toString() +
                                                    FCTran.getValueByDigit(
                                                        shape.m_datas2[crossLineIndex], m_indDigit2
                                                    ))
                                        )
                                        drawColors.add(shape.m_color2)
                                    }
                                }
                            }
                        }
                    }
                }
            }
            if (drawTitles.size > 9) {
                var iLeft = m_leftVScaleWidth + 5
                for (i in drawTitles.indices) {
                    val tSize = paint.textSize(drawTitles[i], font)
                    paint.drawText(
                        drawTitles[i], drawColors[i], font, FCRect(
                            iLeft,
                            candleDivHeight + volDivHeight + indDivHeight + 5 + (tSize.cy / 2),
                            iLeft + tSize.cx,
                            candleDivHeight + volDivHeight + indDivHeight + 5 + (tSize.cy / 2) + tSize.cy
                        )
                    )
                    iLeft += tSize.cx + 5
                }
            }
        }
        if (m_showCrossLine) {
            var rightText: String? = ""
            if (m_touchPosition.y < candleDivHeight) {
                rightText = FCTran.getValueByDigit(
                    getChartValue(m_touchPosition), m_candleDigit
                )
            } else if (m_touchPosition.y > candleDivHeight &&
                m_touchPosition.y < candleDivHeight + volDivHeight
            ) {
                rightText = FCTran.getValueByDigit(
                    getChartValue(m_touchPosition) / m_magnitude, m_volDigit
                )
            } else if (m_touchPosition.y > candleDivHeight + volDivHeight &&
                m_touchPosition.y < candleDivHeight + volDivHeight + indDivHeight
            ) {
                rightText = FCTran.getValueByDigit(
                    getChartValue(m_touchPosition), m_indDigit
                )
            } else if (m_touchPosition.y >
                candleDivHeight + volDivHeight + indDivHeight &&
                m_touchPosition.y <
                candleDivHeight + volDivHeight + indDivHeight + indDivHeight2
            ) {
                rightText = FCTran.getValueByDigit(
                    getChartValue(m_touchPosition), m_indDigit2
                )
            }
            var drawY = m_touchPosition.y
            if (drawY > size.cy - m_hScaleHeight) {
                drawY = size.cy - m_hScaleHeight
            }
            val tSize = paint.textSize(rightText, font)
            if (m_leftVScaleWidth > 0) {
                paint.fillRect(
                    m_crossTipColor, m_leftVScaleWidth - tSize.cx, drawY - (tSize.cy / 2) - 4,
                    m_leftVScaleWidth, drawY + (tSize.cy / 2) + 3
                )
                paint.drawText(
                    rightText, textColor, font,
                    FCRect(
                        m_leftVScaleWidth - tSize.cx,
                        drawY - tSize.cy / 2,
                        m_leftVScaleWidth,
                        drawY + tSize.cy / 2
                    )
                )
            }
            if (m_rightVScaleWidth > 0) {
                paint.fillRect(
                    m_crossTipColor, size.cx - m_rightVScaleWidth, drawY - (tSize.cy / 2) - 4,
                    size.cx - m_rightVScaleWidth + tSize.cx, drawY + (tSize.cy / 2) + 3
                )
                paint.drawText(
                    rightText, textColor, font,
                    FCRect(
                        size.cx - m_rightVScaleWidth,
                        drawY - tSize.cy / 2,
                        size.cx - m_rightVScaleWidth + tSize.cx,
                        drawY + tSize.cy / 2
                    )
                )
            }
            //绘制十字线
            var drawX = getChartX(m_crossStopIndex)
            if (m_targetOldX == 0f && m_targetOldX2 == 0f) {
                drawX = m_touchPosition.x
            }
            if (drawX < m_leftVScaleWidth) {
                drawX = m_leftVScaleWidth
            }
            if (drawX > size.cx - m_rightVScaleWidth) {
                drawX = size.cx - m_rightVScaleWidth
            }
            if (m_showCrossLine && (m_sPlot == null) && (m_selectShape == "")) {
                paint.drawLine(
                    m_crossLineColor, m_lineWidthChart, 0,
                    m_leftVScaleWidth, drawY, size.cx - m_rightVScaleWidth, drawY
                )
                paint.drawLine(
                    m_crossLineColor, m_lineWidthChart, 0, drawX, 0,
                    drawX, size.cy - m_hScaleHeight
                )
            }
            if (m_crossStopIndex != -1) {
                val dateNum = m_datas!![m_crossStopIndex].m_date
                var xText = FCTran.doubleToStr(dateNum)
                val dt: Calendar = FCTran.numToDate(dateNum)
                if (m_hScaleFormat.length > 0) {
                    val format = SimpleDateFormat(m_hScaleFormat)
                    xText = format.format(dt.getTime())
                } else {
                    if ((m_cycle == "day")) {
                        val format = SimpleDateFormat("yyyy-MM-dd")
                        xText = format.format(dt.getTime())
                    } else if ((m_cycle == "minute")) {
                        val format = SimpleDateFormat("HH:mm")
                        xText = format.format(dt.getTime())
                    } else if ((m_cycle == "trend")) {
                        val format = SimpleDateFormat("HH:mm")
                        xText = format.format(dt.getTime())
                    } else if ((m_cycle == "second")) {
                        val format = SimpleDateFormat("HH:mm:ss")
                        xText = format.format(dt.getTime())
                    } else if ((m_cycle == "tick")) {
                        xText = FCTran.intToStr(m_crossStopIndex + 1)
                    }
                }
                val xSize = paint.textSize(xText, font)
                paint.fillRect(
                    m_crossTipColor,
                    drawX - (xSize.cx / 2) - 2,
                    candleDivHeight + volDivHeight + indDivHeight,
                    drawX + (xSize.cx / 2) + 2,
                    candleDivHeight + volDivHeight + indDivHeight + xSize.cy + 6
                )
                paint.drawText(
                    xText, textColor, font, FCRect(
                        drawX - xSize.cx / 2,
                        candleDivHeight + volDivHeight + indDivHeight + 3, drawX + xSize.cx / 2,
                        candleDivHeight + volDivHeight + indDivHeight + 3 + xSize.cy
                    )
                )
            }
        }
    }

    /**
     * 绘制刻度
     * @params paint 绘图对象
     * @params clipRect 裁剪区
     */
    open fun drawChartScale(paint: FCPaint, clipRect: FCRect?) {
        val size = size
        if (m_leftVScaleWidth > 0) {
            paint.drawLine(
                m_scaleColor, m_lineWidthChart, 0,
                m_leftVScaleWidth, 0, m_leftVScaleWidth,
                size.cy - m_hScaleHeight
            )
        }
        if (m_rightVScaleWidth > 0) {
            paint.drawLine(
                m_scaleColor, m_lineWidthChart, 0,
                size.cx - m_rightVScaleWidth, 0, size.cx - m_rightVScaleWidth,
                size.cy - m_hScaleHeight
            )
        }
        if (m_hScaleHeight > 0) {
            paint.drawLine(
                m_scaleColor, m_lineWidthChart, 0, 0,
                size.cy - m_hScaleHeight, size.cx, size.cy - m_hScaleHeight
            )
        }
        val candleDivHeight = candleDivHeight
        val volDivHeight = volDivHeight
        val indDivHeight = indDivHeight
        val indDivHeight2 = indDivHeight2
        if (volDivHeight > 0) {
            paint.drawLine(
                m_scaleColor, m_lineWidthChart, 0,
                m_leftVScaleWidth, candleDivHeight, size.cx - m_rightVScaleWidth, candleDivHeight
            )
        }
        if (indDivHeight > 0) {
            paint.drawLine(
                m_scaleColor, m_lineWidthChart, 0,
                m_leftVScaleWidth, candleDivHeight + volDivHeight,
                size.cx - m_rightVScaleWidth,
                candleDivHeight + volDivHeight
            )
        }
        if (indDivHeight2 > 0) {
            paint.drawLine(
                m_scaleColor, m_lineWidthChart, 0,
                m_leftVScaleWidth, candleDivHeight + volDivHeight + indDivHeight,
                size.cx - m_rightVScaleWidth,
                candleDivHeight + volDivHeight + indDivHeight
            )
        }
        if (m_datas!!.size > 0) {
            var topPoint = FCPoint(0, 20)
            var bottomPoint = FCPoint(0, candleDivHeight - 10)
            val candleMax = getChartValue(topPoint)
            val candleMin = getChartValue(bottomPoint)
            chartGridScale(
                candleMin,
                candleMax,
                (candleDivHeight - m_candlePaddingTop - m_candlePaddingBottom) / 2,
                m_vScaleDistance.toDouble(),
                (m_vScaleDistance / 2).toDouble(),
                (candleDivHeight - m_candlePaddingTop - m_candlePaddingBottom) / m_vScaleDistance
            )
            if (m_gridStep > 0) {
                val drawValues = ArrayList<Double>()
                val isTrend = (m_cycle == "trend")
                var firstOpen = m_firstOpen
                if (isTrend) {
                    if (firstOpen == 0.0) {
                        firstOpen = m_datas!![m_firstVisibleIndex].m_close
                    }
                    var subValue = (candleMax - candleMin)
                    val count = ((candleDivHeight -
                            m_candlePaddingTop -
                            m_candlePaddingBottom)) /
                            m_vScaleDistance
                    if (count > 0) {
                        subValue /= count.toDouble()
                    }
                    var start = firstOpen
                    while (start < candleMax) {
                        start += subValue
                        if (start <= candleMax) {
                            drawValues.add(start)
                        }
                    }
                    start = firstOpen
                    while (start > candleMin) {
                        start -= subValue
                        if (start >= candleMin) {
                            drawValues.add(start)
                        }
                    }
                } else {
                    var start = 0.0
                    if (candleMin >= 0) {
                        while (start + m_gridStep < candleMin) {
                            start += m_gridStep
                        }
                    } else {
                        while (start - m_gridStep > candleMin) {
                            start -= m_gridStep
                        }
                    }
                    while (start <= candleMax) {
                        if (start > candleMin) {
                            drawValues.add(start)
                        }
                        start += m_gridStep
                    }
                }
                drawValues.add(firstOpen)
                for (i in drawValues.indices) {
                    val start = drawValues[i]
                    val hAxisY = getChartY(0, start)
                    if (hAxisY < 1 || hAxisY > candleDivHeight) {
                        continue
                    }
                    paint.drawLine(
                        m_gridColor, m_lineWidthChart, 0,
                        m_leftVScaleWidth, hAxisY,
                        size.cx - m_rightVScaleWidth, hAxisY
                    )
                    paint.drawLine(
                        m_scaleColor, m_lineWidthChart, 0,
                        m_leftVScaleWidth - 8, hAxisY, m_leftVScaleWidth, hAxisY
                    )
                    paint.drawLine(
                        m_scaleColor, m_lineWidthChart, 0,
                        size.cx - m_rightVScaleWidth, hAxisY,
                        size.cx - m_rightVScaleWidth + 8, hAxisY
                    )
                    val drawText = FCTran.getValueByDigit(start, m_candleDigit)
                    val tSize = paint.textSize(drawText, font)
                    if (isTrend) {
                        val diffRange = ((start - firstOpen) / firstOpen * 100)
                        val diffRangeStr = FCTran.getValueByDigit(diffRange, 2) + "%".toString()
                        val dSize = paint.textSize(diffRangeStr, font)
                        if (diffRange >= 0) {
                            paint.drawText(
                                diffRangeStr, m_upColor, font,
                                FCRect(
                                    size.cx - m_rightVScaleWidth + 10,
                                    hAxisY - tSize.cy / 2,
                                    (size.cx - m_rightVScaleWidth) + 10 + dSize.cx,
                                    hAxisY + tSize.cy / 2
                                )
                            )
                        } else {
                            paint.drawText(
                                diffRangeStr, m_downColor, font,
                                FCRect(
                                    size.cx - m_rightVScaleWidth + 10,
                                    hAxisY - tSize.cy / 2,
                                    (size.cx - m_rightVScaleWidth) + 10 + dSize.cx,
                                    hAxisY + tSize.cy / 2
                                )
                            )
                        }
                    } else {
                        if (m_vScaleTextColor != FCColor.None) {
                            paint.drawText(
                                drawText, m_vScaleTextColor, font, FCRect(
                                    size.cx - m_rightVScaleWidth + 10,
                                    hAxisY - tSize.cy / 2,
                                    (size.cx - m_rightVScaleWidth) + 10 + tSize.cx,
                                    hAxisY + tSize.cy / 2
                                )
                            )
                        } else {
                            paint.drawText(
                                drawText, textColor, font, FCRect(
                                    size.cx - m_rightVScaleWidth + 10,
                                    hAxisY - tSize.cy / 2,
                                    (size.cx - m_rightVScaleWidth) + 10 + tSize.cx,
                                    hAxisY + tSize.cy / 2
                                )
                            )
                        }
                    }
                    if (m_vScaleTextColor != FCColor.None) {
                        paint.drawText(
                            drawText, m_vScaleTextColor, font,
                            FCRect(
                                m_leftVScaleWidth - tSize.cx - 10,
                                hAxisY - tSize.cy / 2,
                                m_leftVScaleWidth - 10,
                                hAxisY + tSize.cy / 2
                            )
                        )
                    } else {
                        paint.drawText(
                            drawText, textColor, font,
                            FCRect(
                                m_leftVScaleWidth - tSize.cx - 10,
                                hAxisY - tSize.cy / 2,
                                m_leftVScaleWidth - 10,
                                hAxisY + tSize.cy / 2
                            )
                        )
                    }
                }
            }
            topPoint = FCPoint(0, candleDivHeight + 10)
            bottomPoint = FCPoint(0, candleDivHeight + volDivHeight - 10)
            val volMax = getChartValue(topPoint)
            val volMin = getChartValue(bottomPoint)
            chartGridScale(
                volMin, volMax, (volDivHeight - m_volPaddingTop - m_volPaddingBottom) / 2,
                m_vScaleDistance.toDouble(), (m_vScaleDistance / 2).toDouble(),
                (volDivHeight - m_volPaddingTop - m_volPaddingBottom) / m_vScaleDistance
            )
            if (m_gridStep > 0) {
                var start = 0.0
                if (volMin >= 0) {
                    while (start + m_gridStep < volMin) {
                        start += m_gridStep
                    }
                } else {
                    while (start - m_gridStep > volMin) {
                        start -= m_gridStep
                    }
                }
                while (start <= volMax) {
                    if (start > volMin) {
                        val hAxisY = getChartY(1, start)
                        if (hAxisY < candleDivHeight ||
                            hAxisY > candleDivHeight + volDivHeight
                        ) {
                            start += m_gridStep
                            continue
                        }
                        paint.drawLine(
                            m_gridColor, m_lineWidthChart, 0, m_leftVScaleWidth,
                            hAxisY, size.cx - m_rightVScaleWidth, hAxisY
                        )
                        paint.drawLine(
                            m_scaleColor, m_lineWidthChart, 0,
                            m_leftVScaleWidth - 8, hAxisY, m_leftVScaleWidth, hAxisY
                        )
                        paint.drawLine(
                            m_scaleColor, m_lineWidthChart, 0, size.cx - m_rightVScaleWidth,
                            hAxisY, size.cx - m_rightVScaleWidth + 8, hAxisY
                        )
                        val drawText = FCTran.getValueByDigit(start / m_magnitude, m_volDigit)
                        val tSize = paint.textSize(drawText, font)
                        if (m_vScaleTextColor != FCColor.None) {
                            paint.drawText(
                                drawText, m_vScaleTextColor, font,
                                FCRect(
                                    size.cx - m_rightVScaleWidth + 10,
                                    hAxisY - tSize.cy / 2,
                                    (size.cx - m_rightVScaleWidth) + 10 + tSize.cx,
                                    hAxisY + tSize.cy / 2
                                )
                            )
                            paint.drawText(
                                drawText, m_vScaleTextColor, font,
                                FCRect(
                                    m_leftVScaleWidth - tSize.cx - 10,
                                    hAxisY - tSize.cy / 2,
                                    m_leftVScaleWidth - 10,
                                    hAxisY + tSize.cy / 2
                                )
                            )
                        } else {
                            paint.drawText(
                                drawText, textColor, font,
                                FCRect(
                                    size.cx - m_rightVScaleWidth + 10,
                                    hAxisY - tSize.cy / 2,
                                    (size.cx - m_rightVScaleWidth) + 10 + tSize.cx,
                                    hAxisY + tSize.cy / 2
                                )
                            )
                            paint.drawText(
                                drawText, textColor, font,
                                FCRect(
                                    m_leftVScaleWidth - tSize.cx - 10,
                                    hAxisY - tSize.cy / 2,
                                    m_leftVScaleWidth - 10,
                                    hAxisY + tSize.cy / 2
                                )
                            )
                        }
                    }
                    start += m_gridStep
                }
            }
            if (indDivHeight > 0) {
                topPoint = FCPoint(0, candleDivHeight + volDivHeight + 10)
                bottomPoint = FCPoint(0, candleDivHeight + volDivHeight + indDivHeight - 10)
                val indMax = getChartValue(topPoint)
                val indMin = getChartValue(bottomPoint)
                chartGridScale(
                    indMin, indMax, (indDivHeight - m_indPaddingTop - m_indPaddingBottom) / 2,
                    m_vScaleDistance.toDouble(), (m_vScaleDistance / 2).toDouble(),
                    (indDivHeight - m_indPaddingTop - m_indPaddingBottom) / m_vScaleDistance
                )
                if (m_gridStep > 0) {
                    var start = 0.0
                    if (indMin >= 0) {
                        while (start + m_gridStep < indMin) {
                            start += m_gridStep
                        }
                    } else {
                        while (start - m_gridStep > indMin) {
                            start -= m_gridStep
                        }
                    }
                    while (start <= indMax) {
                        if (start > indMin) {
                            val hAxisY = getChartY(2, start)
                            if (hAxisY < candleDivHeight + volDivHeight ||
                                hAxisY > candleDivHeight + volDivHeight + indDivHeight
                            ) {
                                start += m_gridStep
                                continue
                            }
                            paint.drawLine(
                                m_gridColor,
                                m_lineWidthChart,
                                0,
                                m_leftVScaleWidth,
                                hAxisY,
                                size.cx - m_rightVScaleWidth,
                                hAxisY
                            )
                            paint.drawLine(
                                m_scaleColor,
                                m_lineWidthChart,
                                0,
                                m_leftVScaleWidth - 8,
                                hAxisY,
                                m_leftVScaleWidth,
                                hAxisY
                            )
                            paint.drawLine(
                                m_scaleColor,
                                m_lineWidthChart,
                                0,
                                size.cx - m_rightVScaleWidth,
                                hAxisY,
                                size.cx - m_rightVScaleWidth + 8,
                                hAxisY
                            )
                            val drawText = FCTran.getValueByDigit(start, m_indDigit)
                            val tSize = paint.textSize(drawText, font)
                            if (m_vScaleTextColor != FCColor.None) {
                                paint.drawText(
                                    drawText, m_vScaleTextColor, font,
                                    FCRect(
                                        size.cx - m_rightVScaleWidth + 10,
                                        hAxisY - tSize.cy / 2,
                                        (size.cx - m_rightVScaleWidth) + 10 + tSize.cx,
                                        hAxisY + tSize.cy / 2
                                    )
                                )
                                paint.drawText(
                                    drawText, m_vScaleTextColor, font,
                                    FCRect(
                                        m_leftVScaleWidth - tSize.cx - 10,
                                        hAxisY - tSize.cy / 2,
                                        m_leftVScaleWidth - 10,
                                        hAxisY + tSize.cy / 2
                                    )
                                )
                            } else {
                                paint.drawText(
                                    drawText, textColor, font,
                                    FCRect(
                                        size.cx - m_rightVScaleWidth + 10,
                                        hAxisY - tSize.cy / 2,
                                        (size.cx - m_rightVScaleWidth) + 10 + tSize.cx,
                                        hAxisY + tSize.cy / 2
                                    )
                                )
                                paint.drawText(
                                    drawText, textColor, font,
                                    FCRect(
                                        m_leftVScaleWidth - tSize.cx - 10,
                                        hAxisY - tSize.cy / 2,
                                        m_leftVScaleWidth - 10,
                                        hAxisY + tSize.cy / 2
                                    )
                                )
                            }
                        }
                        start += m_gridStep
                    }
                }
            }
            if (indDivHeight2 > 0) {
                topPoint = FCPoint(0, candleDivHeight + volDivHeight + indDivHeight + 10)
                bottomPoint = FCPoint(
                    0,
                    candleDivHeight + volDivHeight + indDivHeight + indDivHeight2 - 10
                )
                val indMax2 = getChartValue(topPoint)
                val indMin2 = getChartValue(bottomPoint)
                chartGridScale(
                    indMin2,
                    indMax2,
                    (indDivHeight2 - m_indPaddingTop2 - m_indPaddingBottom2) / 2,
                    m_vScaleDistance.toDouble(),
                    (m_vScaleDistance / 2).toDouble(),
                    (indDivHeight2 - m_indPaddingTop2 - m_indPaddingBottom2) /
                            m_vScaleDistance
                )
                if (m_gridStep > 0) {
                    var start = 0.0
                    if (indMin2 >= 0) {
                        while (start + m_gridStep < indMin2) {
                            start += m_gridStep
                        }
                    } else {
                        while (start - m_gridStep > indMin2) {
                            start -= m_gridStep
                        }
                    }
                    while (start <= indMax2) {
                        if (start > indMin2) {
                            val hAxisY = getChartY(3, start)
                            if (hAxisY < candleDivHeight + volDivHeight + indDivHeight || hAxisY > candleDivHeight + volDivHeight + indDivHeight + indDivHeight2) {
                                start += m_gridStep
                                continue
                            }
                            paint.drawLine(
                                m_gridColor,
                                m_lineWidthChart,
                                0,
                                m_leftVScaleWidth,
                                hAxisY,
                                size.cx - m_rightVScaleWidth,
                                hAxisY
                            )
                            paint.drawLine(
                                m_scaleColor,
                                m_lineWidthChart,
                                0,
                                m_leftVScaleWidth - 8,
                                hAxisY,
                                m_leftVScaleWidth,
                                hAxisY
                            )
                            paint.drawLine(
                                m_scaleColor,
                                m_lineWidthChart,
                                0,
                                size.cx - m_rightVScaleWidth,
                                hAxisY,
                                size.cx - m_rightVScaleWidth + 8,
                                hAxisY
                            )
                            val drawText = FCTran.getValueByDigit(start, m_indDigit)
                            val tSize = paint.textSize(drawText, font)
                            if (m_vScaleTextColor != FCColor.None) {
                                paint.drawText(
                                    drawText,
                                    m_vScaleTextColor,
                                    font,
                                    FCRect(
                                        size.cx - m_rightVScaleWidth + 10,
                                        hAxisY - tSize.cy / 2,
                                        (size.cx - m_rightVScaleWidth) + 10 + tSize.cx,
                                        hAxisY + tSize.cy / 2
                                    )
                                )
                                paint.drawText(
                                    drawText, m_vScaleTextColor, font,
                                    FCRect(
                                        m_leftVScaleWidth - tSize.cx - 10,
                                        hAxisY - tSize.cy / 2,
                                        m_leftVScaleWidth - 10,
                                        hAxisY + tSize.cy / 2
                                    )
                                )
                            } else {
                                paint.drawText(
                                    drawText,
                                    textColor,
                                    font,
                                    FCRect(
                                        size.cx - m_rightVScaleWidth + 10,
                                        hAxisY - tSize.cy / 2,
                                        (size.cx - m_rightVScaleWidth) + 10 + tSize.cx,
                                        hAxisY + tSize.cy / 2
                                    )
                                )
                                paint.drawText(
                                    drawText, textColor, font,
                                    FCRect(
                                        m_leftVScaleWidth - tSize.cx - 10,
                                        hAxisY - tSize.cy / 2,
                                        m_leftVScaleWidth - 10,
                                        hAxisY + tSize.cy / 2
                                    )
                                )
                            }
                        }
                        start += m_gridStep
                    }
                }
            }
        }
        if (m_datas!!.size > 0 && m_hScaleHeight > 0) {
            val dLeft = (m_leftVScaleWidth + 10).toDouble()
            var i = m_firstVisibleIndex
            while (i <= m_lastVisibleIndex) {
                val dateNum = m_datas!![i].m_date
                var xText = FCTran.doubleToStr(dateNum)
                val dt: Calendar = FCTran.numToDate(dateNum)
                if (m_hScaleFormat.length > 0) {
                    val format = SimpleDateFormat(m_hScaleFormat)
                    xText = format.format(dt.getTime())
                } else {
                    if ((m_cycle == "day")) {
                        val format = SimpleDateFormat("yyyy-MM-dd")
                        xText = format.format(dt.getTime())
                    } else if ((m_cycle == "minute")) {
                        val format = SimpleDateFormat("HH:mm")
                        xText = format.format(dt.getTime())
                    } else if ((m_cycle == "trend")) {
                        val format = SimpleDateFormat("HH:mm")
                        xText = format.format(dt.getTime())
                    } else if ((m_cycle == "second")) {
                        val format = SimpleDateFormat("HH:mm:ss")
                        xText = format.format(dt.getTime())
                    } else if ((m_cycle == "tick")) {
                        xText = FCTran.intToStr(m_crossStopIndex + 1)
                    }
                }
                val tSize = paint.textSize(xText, font)
                val x = getChartX(i)
                val dx = x - tSize.cx / 2
                if (dx > dLeft && dx < size.cx - m_rightVScaleWidth - 10) {
                    paint.drawLine(
                        m_scaleColor,
                        m_lineWidthChart,
                        0,
                        x,
                        size.cy - m_hScaleHeight,
                        x,
                        size.cy - m_hScaleHeight + 8
                    )
                    if (m_hScaleTextColor != FCColor.None) {
                        paint.drawText(
                            xText,
                            m_hScaleTextColor,
                            font,
                            FCRect(
                                dx,
                                size.cy - m_hScaleHeight + 8 - tSize.cy / 2 + 7,
                                dx + tSize.cx,
                                (size.cy - m_hScaleHeight) + 8 + (tSize.cy / 2) + 7
                            )
                        )
                    } else {
                        paint.drawText(
                            xText,
                            textColor,
                            font,
                            FCRect(
                                dx,
                                size.cy - m_hScaleHeight + 8 - tSize.cy / 2 + 7,
                                dx + tSize.cx,
                                (size.cy - m_hScaleHeight) + 8 + (tSize.cy / 2) + 7
                            )
                        )
                    }
                    i = i + (((tSize.cx + m_hScaleTextDistance) / m_hScalePixel).toInt()) + 1
                }
                i++
            }
        }
    }

    /**
     * 根据三点计算圆心
     * @params x1 横坐标1
     * @params y1 纵坐标1
     * @params x2 横坐标2
     * @params y2 纵坐标2
     * @params x3 横坐标3
     * @params y3 纵坐标3
     */
    fun ellipseOR(x1: Double, y1: Double, x2: Double, y2: Double, x3: Double, y3: Double) {
        m_oXChart = ((y3 - y1) * (y2 * y2 - y1 * y1 + x2 * x2 - x1 * x1) +
                (y2 - y1) * (y1 * y1 - y3 * y3 + x1 * x1 - x3 * x3)) /
                (2 * (x2 - x1) * (y3 - y1) - 2 * (x3 - x1) * (y2 - y1))
        m_oYChart = ((x3 - x1) * (x2 * x2 - x1 * x1 + y2 * y2 - y1 * y1) +
                (x2 - x1) * (x1 * x1 - x3 * x3 + y1 * y1 - y3 * y3)) /
                (2 * (y2 - y1) * (x3 - x1) - 2 * (y3 - y1) * (x2 - x1))
        m_rChart =
            Math.sqrt((x1 - m_oXChart) * (x1 - m_oXChart) + (y1 - m_oYChart) * (y1 - m_oYChart))
    }

    /**
     * 判断点是否在椭圆上
     * @params x 横坐标
     * @params y 纵坐标
     * @params oX 坐标起始X
     * @params oY 坐标起始Y
     * @params a 椭圆参数a
     * @params b 椭圆参数b
     */
    fun ellipseHasPoint(
        x: Double,
        y: Double,
        oX: Double,
        oY: Double,
        a: Double,
        b: Double
    ): Boolean {
        var x = x
        var y = y
        x -= oX
        y -= oY
        if ((a == 0.0) && (b == 0.0) && (x == 0.0) && (y == 0.0)) {
            return true
        }
        if (a == 0.0) {
            if ((x == 0.0) && (y >= -b) && (y <= b)) {
                return false
            }
        }
        if (b == 0.0) {
            if ((y == 0.0) && (x >= -a) && (x <= a)) {
                return true
            }
        }
        return if ((x * x) / (a * a) + (y * y) / (b * b) >= 0.8 &&
            (x * x) / (a * a) + (y * y) / (b * b) <= 1.2
        ) {
            true
        } else false
    }

    /**
     * 计算斐波那契数列
     * @params index 索引
     */
    fun fibonacciValue(index: Int): Int {
        if (index < 1) {
            return 0
        } else {
            val vList = ArrayList<Int>()
            for (i in 0 until index) {
                vList.add(0)
            }
            var result = 0
            for (i in 0..(index - 1)) {
                if (i == 0 || i == 1) {
                    vList[i] = 1
                } else {
                    vList[i] = vList[i - 1] + vList[i - 2]
                }
            }
            result = vList[index - 1]
            return result
        }
    }

    /**
     * 获取视图类型
     */
    override fun getViewType(): String {
        return "Chart"
    }

    /**
     * 获取图表的区域
     * @params plot 画线
     */
    fun getCandleRange(plot: FCPlot) {
        var bIndex = getChartIndexByDate(plot.m_key1)
        var eIndex = getChartIndexByDate(plot.m_key2)
        val tempBIndex = Math.min(bIndex, eIndex)
        val tempEIndex = Math.max(bIndex, eIndex)
        bIndex = tempBIndex
        eIndex = tempEIndex
        val highList = ArrayList<Double>()
        val lowList = ArrayList<Double>()
        for (i in bIndex..eIndex) {
            highList.add(m_datas!![i].m_high)
            lowList.add(m_datas!![i].m_low)
        }
        m_nHighChart = maxValue(highList)
        m_nLowChart = minValue(lowList)
    }

    /**
     * 计算EMA
     * @params n 周期
     * @params value 当前数据
     * @params lastEMA 上期数据
     */
    fun getEMA(n: Int, value: Double, lastEMA: Double): Double {
        return (value * 2 + lastEMA * (n - 1)) / (n + 1)
    }

    /**
     * 计算MACD
     * @params dif DIF数据
     * @params dea DEA数据
     */
    fun getMACD(dif: ArrayList<Double>, dea: ArrayList<Double>): ArrayList<Double> {
        val result = ArrayList<Double>()
        for (i in dif.indices) {
            result.add((dif[i] - dea[i]) * 2)
        }
        return result
    }

    /**
     * 计算DIF
     * @params close12 12日数据
     * @params close26 26日数据
     */
    fun getDIF(close12: ArrayList<Double>, close26: ArrayList<Double>): ArrayList<Double> {
        val result = ArrayList<Double>()
        for (i in close12.indices) {
            result.add(close12[i] - close26[i])
        }
        return result
    }

    /**
     * 根据日期获取索引
     * @params date 日期
     */
    fun getChartIndexByDate(date: Double): Int {
        var index = -1
        for (i in m_datas!!.indices) {
            if (m_datas!![i].m_date == date) {
                index = i
                break
            }
        }
        return index
    }

    /**
     * 获取百分比线的刻度
     * @params y1 纵坐标1
     * @params y2 纵坐标2
     */
    fun getPercentParams(y1: Double, y2: Double): ArrayList<Int> {
        var y0 = 0.0
        var y25 = 0.0
        var y50 = 0.0
        var y75 = 0.0
        var y100 = 0.0
        y0 = y1
        y25 = if (y1 <= y2) y1 + (y2 - y1) / 4 else y2 + (y1 - y2) * 3 / 4
        y50 = if (y1 <= y2) y1 + (y2 - y1) / 2 else y2 + (y1 - y2) / 2
        y75 = if (y1 <= y2) y1 + (y2 - y1) * 3 / 4 else y2 + (y1 - y2) / 4
        y100 = y2
        val list = ArrayList<Int>()
        list.add(y0.toInt())
        list.add(y25.toInt())
        list.add(y50.toInt())
        list.add(y75.toInt())
        list.add(y100.toInt())
        return list
    }

    /**
     * 获取TRIX的数据
     */
    fun getTRIXData(
        ticks: ArrayList<Double>,
        m: Int,
        trixArr: ArrayList<Double>,
        matrixArr: ArrayList<Double>
    ) {
        val length = ticks.size
        val mtrArr = ArrayList<Double>()
        val emaArr1 = ArrayList<Double>()
        emaArr1.add(ticks[0])
        for (i in 1 until length) {
            emaArr1.add(getEMA(m, ticks[i], emaArr1[i - 1]))
        }
        val emaArr2 = ArrayList<Double>()
        emaArr2.add(emaArr1[0])
        for (i in 1 until length) {
            emaArr2.add(getEMA(m, emaArr1[i], emaArr2[i - 1]))
        }
        mtrArr.add(emaArr2[0])
        for (i in 1 until length) {
            mtrArr.add(getEMA(m, emaArr2[i], mtrArr[i - 1]))
        }
        val refV = refValue(mtrArr, 1)
        for (i in 0 until length) {
            val trix = 100 * (mtrArr[i] - refV[i]) / refV[i]
            trixArr.add(trix)
        }
        val matrixArrCopy = maValue(trixArr, m)
        for (i in matrixArrCopy.indices) {
            matrixArr.add(matrixArrCopy[i])
        }
    }

    /**
     * 计算boll指标
     */
    fun getBollData(
        ticks: ArrayList<Double>,
        maDays: Int,
        ups: ArrayList<Double>,
        mas: ArrayList<Double>,
        lows: ArrayList<Double>
    ) {
        val tickBegin = maDays - 1
        var maSum = 0.0
        var p = 0.0
        for (i in ticks.indices) {
            val c = ticks[i]
            var ma = 0.0
            var md = 0.0
            var bstart = 0
            var mdSum = 0.0
            maSum = maSum + c
            if (i >= tickBegin) {
                maSum = maSum - p
                ma = maSum / maDays
                bstart = i - tickBegin
                p = ticks[bstart]
                mas.add(ma)
                bstart = i - tickBegin
                p = ticks[bstart]
                val values = ArrayList<Double>()
                for (j in bstart until (bstart + maDays)) {
                    values.add(ticks[j])
                }
                mdSum = standardDeviationSum(values, ma)
                md = Math.sqrt(mdSum / maDays)
                ups.add(ma + 2 * md)
                lows.add(ma - 2 * md)
            } else {
                ma = maSum / (i + 1)
                mas.add(ma)
                val values = ArrayList<Double>()
                for (j in 0 until (i + 1)) {
                    values.add(ticks[j])
                }
                mdSum = standardDeviationSum(values, ma)
                md = Math.sqrt(mdSum / (i + 1))
                ups.add(ma + 2 * md)
                lows.add(ma - 2 * md)
            }
        }
    }

    /**
     * 计算kdj指标
     */
    fun getKDJData(
        highArr: ArrayList<Double>,
        lowArr: ArrayList<Double>,
        closeArr: ArrayList<Double>,
        n: Int,
        m1: Int,
        m2: Int,
        ks: ArrayList<Double>,
        ds: ArrayList<Double>,
        js: ArrayList<Double>
    ) {
        val rsvs = ArrayList<Double>()
        var lastK = 0.0
        var lastD = 0.0
        var curK = 0.0
        var curD = 0.0
        for (i in closeArr.indices) {
            val highList = ArrayList<Double>()
            val lowList = ArrayList<Double>()
            var startIndex = i - n
            if (startIndex < 0) {
                startIndex = 0
            }
            for (j in startIndex..i) {
                highList.add(highArr[j])
                lowList.add(lowArr[j])
            }
            val close = closeArr[i]
            var maxHigh = 0.0
            var minLow = 0.0
            for (m in highList.indices) {
                val high = highList[m]
                val low = lowList[m]
                if (high > maxHigh) {
                    maxHigh = high
                }
                if (low < minLow) {
                    minLow = low
                }
            }
            if (maxHigh == minLow) {
                rsvs.add(0.0)
            } else {
                rsvs.add(100 * (close - minLow) / (maxHigh - minLow))
            }
            if (i == 0) {
                lastK = rsvs[i]
                lastD = rsvs[i]
            }
            curK = lastK * (m1 - 1) / m1 + 1.0 / m1 * rsvs[i]
            ks.add(curK)
            lastK = curK
            curD = lastD * (m2 - 1) / m2 + 1.0 / m2 * curK
            ds.add(curD)
            lastD = curD
            js.add(3.0 * curK - 2.0 * curD)
        }
    }

    /**
     * 计算rsi指标
     */
    fun getRSIData(
        ticks: ArrayList<Double>,
        n1: Int,
        n2: Int,
        n3: Int,
        rsi1: ArrayList<Double>,
        rsi2: ArrayList<Double>,
        rsi3: ArrayList<Double>
    ) {
        var lastClosePx = ticks[0]
        var lastSm1 = 0.0
        var lastSa1 = 0.0
        var lastSm2 = 0.0
        var lastSa2 = 0.0
        var lastSm3 = 0.0
        var lastSa3 = 0.0
        for (i in ticks.indices) {
            val c = ticks[i]
            val m = Math.max(c - lastClosePx, 0.0)
            val a = Math.abs(c - lastClosePx)
            if (i == 0) {
                lastSm1 = 0.0
                lastSa1 = 0.0
                rsi1.add(0.0)
            } else {
                lastSm1 = (m + (n1 - 1) * lastSm1) / n1
                lastSa1 = (a + (n1 - 1) * lastSa1) / n1
                if (lastSa1 != 0.0) {
                    rsi1.add(lastSm1 / lastSa1 * 100)
                } else {
                    rsi1.add(0.0)
                }
            }
            if (i == 0) {
                lastSm2 = 0.0
                lastSa2 = 0.0
                rsi2.add(0.0)
            } else {
                lastSm2 = (m + (n2 - 1) * lastSm2) / n2
                lastSa2 = (a + (n2 - 1) * lastSa2) / n2
                if (lastSa2 != 0.0) {
                    rsi2.add(lastSm2 / lastSa2 * 100)
                } else {
                    rsi2.add(0.0)
                }
            }
            if (i == 0) {
                lastSm3 = 0.0
                lastSa3 = 0.0
                rsi3.add(0.0)
            } else {
                lastSm3 = (m + (n3 - 1) * lastSm3) / n3
                lastSa3 = (a + (n3 - 1) * lastSa3) / n3
                if (lastSa3 != 0.0) {
                    rsi3.add(lastSm3 / lastSa3 * 100)
                } else {
                    rsi3.add(0.0)
                }
            }
            lastClosePx = c
        }
    }

    /**
     * 计算ROC数据
     */
    fun getRocData(
        ticks: ArrayList<Double>,
        n: Int,
        m: Int,
        roc: ArrayList<Double>,
        maroc: ArrayList<Double>
    ) {
        for (i in ticks.indices) {
            var currRoc = 0.0
            if (i >= n) {
                currRoc = 100 * (ticks[i] - ticks[i - n]) / ticks[i - n]
                roc.add(currRoc)
            } else {
                currRoc = 100 * (ticks[i] - ticks[0]) / ticks[0]
                roc.add(currRoc)
            }
        }
        val marocMA = maValue(roc, m)
        for (i in marocMA.indices) {
            maroc.add(marocMA[i])
        }
    }

    /**
     * 获取BIAS的数据
     */
    fun getBIASData(
        ticks: ArrayList<Double>,
        n1: Int,
        n2: Int,
        n3: Int,
        bias1Arr: ArrayList<Double>,
        bias2Arr: ArrayList<Double>,
        bias3Arr: ArrayList<Double>
    ) {
        val ma1 = maValue(ticks, n1)
        val ma2 = maValue(ticks, n2)
        val ma3 = maValue(ticks, n3)
        for (i in ticks.indices) {
            val b1 = (ticks[i] - ma1[i]) / ma1[i] * 100
            val b2 = (ticks[i] - ma2[i]) / ma2[i] * 100
            val b3 = (ticks[i] - ma3[i]) / ma3[i] * 100
            bias1Arr.add(b1)
            bias2Arr.add(b2)
            bias3Arr.add(b3)
        }
    }

    /**
     * 计算DMA（平均差）
     */
    fun getDMAData(
        ticks: ArrayList<Double>,
        n1: Int,
        n2: Int,
        difArr: ArrayList<Double>,
        difmaArr: ArrayList<Double>
    ) {
        val ma10 = maValue(ticks, n1)
        val ma50 = maValue(ticks, n2)
        for (i in ticks.indices) {
            val dif = ma10[i] - ma50[i]
            difArr.add(dif)
        }
        val difma = maValue(difArr, n1)
        for (i in difma.indices) {
            difmaArr.add(difma[i])
        }
    }

    /**
     * 计算BBI(多空指标)
     */
    fun getBBIData(
        ticks: ArrayList<Double>,
        n1: Int,
        n2: Int,
        n3: Int,
        n4: Int,
        bbiArr: ArrayList<Double>
    ) {
        val ma3 = maValue(ticks, n1)
        val ma6 = maValue(ticks, n2)
        val ma12 = maValue(ticks, n3)
        val ma24 = maValue(ticks, n4)
        for (i in ticks.indices) {
            val bbi = (ma3[i] + ma6[i] + ma12[i] + ma24[i]) / 4
            bbiArr.add(bbi)
        }
    }

    /**
     * 计算WR(威廉指标)
     */
    fun getWRData(
        highArr: ArrayList<Double>,
        lowArr: ArrayList<Double>,
        closeArr: ArrayList<Double>,
        n1: Int,
        n2: Int,
        wr1Arr: ArrayList<Double>,
        wr2Arr: ArrayList<Double>
    ) {
        val highArr1 = hhvValue(highArr, n1)
        val highArr2 = hhvValue(highArr, n2)
        val lowArr1 = llvValue(lowArr, n1)
        val lowArr2 = llvValue(lowArr, n2)
        for (i in closeArr.indices) {
            val high1 = highArr1[i]
            val low1 = lowArr1[i]
            val high2 = highArr2[i]
            val low2 = lowArr2[i]
            val close = closeArr[i]
            val wr1 = 100 * (high1 - close) / (high1 - low1)
            val wr2 = 100 * (high2 - close) / (high2 - low2)
            wr1Arr.add(wr1)
            wr2Arr.add(wr2)
        }
    }

    /**
     * CCI(顺势指标)计算  CCI（N日）=（TP－MA）÷MD÷0.015
     */
    fun getCCIData(
        highArr: ArrayList<Double>,
        lowArr: ArrayList<Double>,
        closeArr: ArrayList<Double>,
        n: Int,
        cciArr: ArrayList<Double>
    ) {
        val tpArr = ArrayList<Double>()
        for (i in closeArr.indices) {
            tpArr.add((closeArr[i] + highArr[i] + lowArr[i]) / 3)
        }
        val maClose = maValue(closeArr, n)
        val mdArr = ArrayList<Double>()
        for (i in closeArr.indices) {
            mdArr.add(maClose[i] - closeArr[i])
        }
        val maMD = maValue(mdArr, n)
        for (i in closeArr.indices) {
            var cci = 0.0
            if (maMD[i] > 0) {
                cci = (tpArr[i] - maClose[i]) / (maMD[i] * 0.015)
            }
            cciArr.add(cci)
        }
    }

    /**
     * 根据索引获取横坐标
     * @params index 索引
     */
    fun getChartX(index: Int): Int {
        return (m_leftVScaleWidth + (
                (index - m_firstVisibleIndex) * m_hScalePixel) + (
                m_hScalePixel / 2) + m_offsetX).toInt()
    }

    /**
     * 获取最大显示记录条数
     * @params hScalePixel 间隔
     * @params pureH 横向距离
     */
    fun getChartMaxVisibleCount(hScalePixel: Double, pureH: Double): Int {
        var count = (pureH / hScalePixel).toInt()
        if (count < 0) {
            count = 0
        }
        return count
    }

    val candleDivHeight: Int
        /**
         * 获取图表层的高度
         */
        get() {
            val height = size.cy - m_hScaleHeight
            return if (height > 0) {
                (height * m_candleDivPercent).toInt()
            } else {
                0
            }
        }
    val volDivHeight: Int
        /**
         * 获取成交量层的高度
         */
        get() {
            val height = size.cy - m_hScaleHeight
            return if (height > 0) {
                (height * m_volDivPercent).toInt()
            } else {
                0
            }
        }
    val indDivHeight: Int
        /**
         * 获取指标层的高度
         */
        get() {
            val height = size.cy - m_hScaleHeight
            return if (height > 0) {
                (height * m_indDivPercent).toInt()
            } else {
                0
            }
        }
    val indDivHeight2: Int
        /**
         * 获取指标层2的高度
         */
        get() {
            val height = size.cy - m_hScaleHeight
            return if (height > 0) {
                (height * m_indDivPercent2).toInt()
            } else {
                0
            }
        }
    val chartWorkAreaWidth: Int
        /**
         * 获取横向工作区
         */
        get() = size.cx - m_leftVScaleWidth - m_rightVScaleWidth - m_rightSpace - (m_offsetX.toInt())

    /**
     * 计算线性回归上下限
     * @params plot 画线
     * @params a 直线a
     * @params b 直线b
     */
    fun getLRBandRange(plot: FCPlot, a: Double, b: Double) {
        var bIndex = getChartIndexByDate(plot.m_key1)
        var eIndex = getChartIndexByDate(plot.m_key2)
        val tempBIndex = Math.min(bIndex, eIndex)
        val tempEIndex = Math.max(bIndex, eIndex)
        bIndex = tempBIndex
        eIndex = tempEIndex
        val upList = ArrayList<Double>()
        val downList = ArrayList<Double>()
        for (i in bIndex..eIndex) {
            val high = m_datas!![i].m_high
            val low = m_datas!![i].m_low
            val midValue = (i - bIndex + 1) * a + b
            upList.add(high - midValue)
            downList.add(midValue - low)
        }
        m_upSubValue = maxValue(upList)
        m_downSubValue = maxValue(downList)
    }

    /**
     * 计算数值在层中的位置
     * @params divIndex 所在层
     * @params value 数值
     */
    fun getChartY(divIndex: Int, value: Double): Int {
        if (divIndex == 0) {
            if (m_candleMax > m_candleMin) {
                var cValue = value
                var cMax = m_candleMax
                var cMin = m_candleMin
                if (m_vScaleType != "standard") {
                    if (cValue > 0) {
                        cValue = Math.log(cValue)
                    } else if (cValue < 0) {
                        cValue = -Math.log(Math.abs(cValue))
                    }
                    if (cMax > 0) {
                        cMax = Math.log(cMax)
                    } else if (cMax < 0) {
                        cMax = -Math.log(Math.abs(cMax))
                    }
                    if (cMin > 0) {
                        cMin = Math.log(cMin)
                    } else if (cMin < 0) {
                        cMin = -Math.log(Math.abs(cMin))
                    }
                }
                val rate = (cValue - cMin) / (cMax - cMin)
                val divHeight = candleDivHeight
                return (divHeight - m_candlePaddingBottom - ((divHeight - m_candlePaddingTop - m_candlePaddingBottom) *
                        rate)).toInt()
            } else {
                return 0
            }
        } else if (divIndex == 1) {
            if (m_volMax > m_volMin) {
                val rate = (value - m_volMin) / (m_volMax - m_volMin)
                val candleHeight = candleDivHeight
                val volHeight = volDivHeight
                return ((candleHeight + volHeight) - m_volPaddingBottom - ((volHeight - m_volPaddingTop - m_volPaddingBottom) * rate)).toInt()
            } else {
                return 0
            }
        } else if (divIndex == 2) {
            if (m_indMax > m_indMin) {
                val rate = (value - m_indMin) / (m_indMax - m_indMin)
                val candleHeight = candleDivHeight
                val volHeight = volDivHeight
                val indHeight = indDivHeight
                return ((candleHeight + volHeight + indHeight) - m_indPaddingBottom - ((indHeight - m_indPaddingTop - m_indPaddingBottom) * rate)).toInt()
            } else {
                return 0
            }
        } else if (divIndex == 3) {
            if (m_indMax2 > m_indMin2) {
                val rate = (value - m_indMin2) / (m_indMax2 - m_indMin2)
                val candleHeight = candleDivHeight
                val volHeight = volDivHeight
                val indHeight = indDivHeight
                val indHeight2 = indDivHeight2
                return ((candleHeight + volHeight + indHeight + indHeight2) - m_indPaddingBottom2 - ((indHeight2 - m_indPaddingTop2 - m_indPaddingBottom2) * rate)).toInt()
            } else {
                return 0
            }
        }
        return 0
    }

    /**
     * 根据位置计算索引
     * @params mp 坐标
     */
    fun getChartIndex(mp: FCPoint): Int {
        if (m_datas!!.size == 0) {
            return -1
        }
        if (mp.x <= 0) {
            return 0
        }
        var intX = mp.x - m_leftVScaleWidth - m_hScalePixel - m_offsetX
        if (intX < 0) {
            intX = 0.0
        }
        var index = (m_firstVisibleIndex + intX / m_hScalePixel).toInt()
        val intPixel = m_hScalePixel.toInt()
        if (intPixel > 0 && intX % intPixel != 0.0) {
            index++
        }
        if (index < 0) {
            index = 0
        } else if (index > m_datas!!.size - 1) {
            index = m_datas!!.size - 1
        }
        return index
    }

    /**
     * 根据索引获取日期
     * @params index 坐标
     */
    fun getChartDateByIndex(index: Int): Double {
        var date = 0.0
        if (index >= 0 && index < m_datas!!.size) {
            date = m_datas!![index].m_date
        }
        return date
    }

    /**
     * 根据坐标获取对应的值
     * @params point 坐标
     */
    fun getChartValue(point: FCPoint): Double {
        val candleHeight = candleDivHeight.toDouble()
        val volHeight = volDivHeight.toDouble()
        val indHeight = indDivHeight.toDouble()
        val indHeight2 = indDivHeight.toDouble()
        if (point.y <= candleHeight) {
            if (candleHeight - m_candlePaddingTop - m_candlePaddingBottom > 0) {
                val rate = (candleHeight - m_candlePaddingBottom - point.y) /
                        (candleHeight - m_candlePaddingTop - m_candlePaddingBottom)
                var cMin = m_candleMin
                var cMax = m_candleMax
                if (m_vScaleType != "standard") {
                    if (cMax > 0) {
                        cMax = Math.log(cMax)
                    } else if (cMax < 0) {
                        cMax = -Math.log(Math.abs(cMax))
                    }
                    if (cMin > 0) {
                        cMin = Math.log(cMin)
                    } else if (cMin < 0) {
                        cMin = -Math.log(Math.abs(cMin))
                    }
                }
                val result = cMin + (cMax - cMin) * rate
                return if (!((m_vScaleType == "standard"))) {
                    Math.pow(10.0, result)
                } else {
                    result
                }
            }
        } else if (point.y > candleHeight && point.y <= candleHeight + volHeight) {
            if (volHeight - m_volPaddingTop - m_volPaddingBottom > 0) {
                val rate = (volHeight - m_volPaddingBottom - (point.y - candleHeight)) /
                        (volHeight - m_volPaddingTop - m_volPaddingBottom)
                return m_volMin + (m_volMax - m_volMin) * rate
            }
        } else if (point.y > candleHeight + volHeight &&
            point.y <= candleHeight + volHeight + indHeight
        ) {
            if (indHeight - m_indPaddingTop - m_indPaddingBottom > 0) {
                val rate = ((indHeight -
                        m_indPaddingBottom -
                        (point.y - candleHeight - volHeight))) /
                        (indHeight - m_indPaddingTop - m_indPaddingBottom)
                return m_indMin + (m_indMax - m_indMin) * rate
            }
        } else if (point.y > candleHeight + volHeight + indHeight &&
            point.y <= candleHeight + volHeight + indHeight + indHeight2
        ) {
            if (indHeight2 - m_indPaddingTop2 - m_indPaddingBottom2 > 0) {
                val rate = ((indHeight2 -
                        m_indPaddingBottom2 -
                        (point.y - candleHeight - volHeight - indHeight))) /
                        (indHeight2 - m_indPaddingTop2 - m_indPaddingBottom2)
                return m_indMin2 + (m_indMax2 - m_indMin2) * rate
            }
        }
        return 0.0
    }

    /**
     * 计算数值在层中的右轴位置
     * @params divIndex 所在层
     * @params value 数值
     */
    fun getChartYInRight(divIndex: Int, value: Double): Int {
        if (divIndex == 0) {
            if (m_candleMaxRight > m_candleMinRight) {
                var cValue = value
                var cMax = m_candleMaxRight
                var cMin = m_candleMinRight
                if (m_vScaleType != "standard") {
                    if (cValue > 0) {
                        cValue = Math.log(cValue)
                    } else if (cValue < 0) {
                        cValue = -Math.log(Math.abs(cValue))
                    }
                    if (cMax > 0) {
                        cMax = Math.log(cMax)
                    } else if (cMax < 0) {
                        cMax = -Math.log(Math.abs(cMax))
                    }
                    if (cMin > 0) {
                        cMin = Math.log(cMin)
                    } else if (cMin < 0) {
                        cMin = -Math.log(Math.abs(cMin))
                    }
                }
                val rate = (cValue - cMin) / (cMax - cMin)
                val divHeight = candleDivHeight
                return (divHeight - m_candlePaddingBottom - ((divHeight - m_candlePaddingTop - m_candlePaddingBottom) * rate)).toInt()
            } else {
                return 0
            }
        } else if (divIndex == 1) {
            if (m_volMaxRight > m_volMinRight) {
                val rate = (value - m_volMinRight) / (m_volMaxRight - m_volMinRight)
                val candleHeight = candleDivHeight
                val volHeight = volDivHeight
                return ((candleHeight + volHeight) - m_volPaddingBottom - ((volHeight - m_volPaddingTop - m_volPaddingBottom) * rate)).toInt()
            } else {
                return 0
            }
        } else if (divIndex == 2) {
            if (m_indMaxRight > m_indMinRight) {
                val rate = (value - m_indMinRight) / (m_indMaxRight - m_indMinRight)
                val candleHeight = candleDivHeight
                val volHeight = volDivHeight
                val indHeight = indDivHeight
                return ((candleHeight + volHeight + indHeight) - m_indPaddingBottom - ((indHeight - m_indPaddingTop - m_indPaddingBottom) * rate)).toInt()
            } else {
                return 0
            }
        } else if (divIndex == 3) {
            if (m_indMax2Right > m_indMin2Right) {
                val rate = (value - m_indMin2Right) / (m_indMax2Right - m_indMin2Right)
                val candleHeight = candleDivHeight
                val volHeight = volDivHeight
                val indHeight = indDivHeight
                val indHeight2 = indDivHeight2
                return ((candleHeight + volHeight + indHeight + indHeight2) - m_indPaddingBottom2 - ((indHeight2 - m_indPaddingTop2 - m_indPaddingBottom2) * rate)).toInt()
            } else {
                return 0
            }
        }
        return 0
    }

    /**
     * 根据坐标获取对应的值
     * @params point 坐标
     */
    fun getCandleDivValue(point: FCPoint): Double {
        val candleHeight = candleDivHeight.toDouble()
        var rate = 0.0
        if (candleHeight - m_candlePaddingTop - m_candlePaddingBottom > 0) {
            rate = (candleHeight - m_candlePaddingBottom - point.y) /
                    (candleHeight - m_candlePaddingTop - m_candlePaddingBottom)
        }
        var cMin = m_candleMin
        var cMax = m_candleMax
        if (m_vScaleType != "standard") {
            if (cMax > 0) {
                cMax = Math.log(cMax)
            } else if (cMax < 0) {
                cMax = -Math.log(Math.abs(cMax))
            }
            if (cMin > 0) {
                cMin = Math.log(cMin)
            } else if (cMin < 0) {
                cMin = -Math.log(Math.abs(cMin))
            }
        }
        val result = cMin + (cMax - cMin) * rate
        return if ((m_vScaleType == "standard")) {
            Math.pow(10.0, result)
        } else {
            result
        }
    }

    /**
     * 计算最大值
     * @params ticks 最高价数组
     * @params days 周期
     */
    fun hhvValue(ticks: ArrayList<Double>, days: Int): ArrayList<Double> {
        val hhv = ArrayList<Double>()
        var max = ticks[0]
        for (i in ticks.indices) {
            if (i >= days) {
                max = ticks[i]
                for (j in i downTo (i - days) + 1) {
                    if (max < ticks[j]) {
                        max = ticks[j]
                    }
                }
                hhv.add(max)
            } else {
                if (max < ticks[i]) {
                    max = ticks[i]
                }
                hhv.add(max)
            }
        }
        return hhv
    }

    /**
     * 图表的键盘按下事件
     * @params key 按键
     */
    fun keyDownChart(key: Char) {
        if (key.code == 38) {
            zoomOutChart()
        } else if (key.code == 40) {
            zoomInChart()
        } else if (key.code == 37) {
            scrollLeftChart(1)
        } else if (key.code == 39) {
            scrollRightChart(1)
        }
    }

    /**
     * 判断是否选中图形
     * @params mp 坐标
     */
    fun judgeSelectShape(mp: FCPoint) {
        m_selectShape = ""
        m_selectShapeEx = ""
        val candleHeight = candleDivHeight.toDouble()
        val volHeight = volDivHeight.toDouble()
        val indHeight = indDivHeight.toDouble()
        val indHeight2 = indDivHeight2.toDouble()
        val index = getChartIndex(mp)
        if (mp.y >= candleHeight + volHeight + indHeight &&
            mp.y <= candleHeight + volHeight + indHeight + indHeight2
        ) {
            if ((m_showIndicator2 == "MACD")) {
                if (selectLines(mp, 3, m_allmacdarr, index)) {
                    m_selectShape = m_showIndicator2
                    m_selectShapeEx = "MACD"
                }
                if (selectLines(mp, 3, m_alldifarr, index)) {
                    m_selectShape = m_showIndicator2
                    m_selectShapeEx = "DIF"
                } else if (selectLines(mp, 3, m_alldeaarr, index)) {
                    m_selectShape = m_showIndicator2
                    m_selectShapeEx = "DEA"
                }
            } else if ((m_showIndicator2 == "KDJ")) {
                if (selectLines(mp, 3, m_kdjK, index)) {
                    m_selectShape = m_showIndicator2
                    m_selectShapeEx = "K"
                } else if (selectLines(mp, 3, m_kdjD, index)) {
                    m_selectShape = m_showIndicator2
                    m_selectShapeEx = "D"
                } else if (selectLines(mp, 3, m_kdjJ, index)) {
                    m_selectShape = m_showIndicator2
                    m_selectShapeEx = "J"
                }
            } else if ((m_showIndicator2 == "RSI")) {
                if (selectLines(mp, 3, m_rsi1, index)) {
                    m_selectShape = m_showIndicator2
                    m_selectShapeEx = "6"
                } else if (selectLines(mp, 3, m_rsi2, index)) {
                    m_selectShape = m_showIndicator2
                    m_selectShapeEx = "12"
                } else if (selectLines(mp, 3, m_rsi3, index)) {
                    m_selectShape = m_showIndicator2
                    m_selectShapeEx = "24"
                }
            } else if ((m_showIndicator2 == "BIAS")) {
                if (selectLines(mp, 3, m_bias1, index)) {
                    m_selectShape = m_showIndicator2
                    m_selectShapeEx = "1"
                } else if (selectLines(mp, 3, m_bias2, index)) {
                    m_selectShape = m_showIndicator2
                    m_selectShapeEx = "2"
                } else if (selectLines(mp, 3, m_bias3, index)) {
                    m_selectShape = m_showIndicator2
                    m_selectShapeEx = "3"
                }
            } else if ((m_showIndicator2 == "ROC")) {
                if (selectLines(mp, 3, m_roc, index)) {
                    m_selectShape = m_showIndicator2
                    m_selectShapeEx = "ROC"
                } else if (selectLines(mp, 3, m_rocMa, index)) {
                    m_selectShape = m_showIndicator2
                    m_selectShapeEx = "ROCMA"
                }
            } else if ((m_showIndicator2 == "WR")) {
                if (selectLines(mp, 3, m_wr1, index)) {
                    m_selectShape = m_showIndicator2
                    m_selectShapeEx = "1"
                } else if (selectLines(mp, 3, m_wr2, index)) {
                    m_selectShape = "WR"
                    m_selectShapeEx = "2"
                }
            } else if ((m_showIndicator2 == "CCI")) {
                if (selectLines(mp, 3, m_cci, index)) {
                    m_selectShape = m_showIndicator2
                }
            } else if ((m_showIndicator2 == "BBI")) {
                if (selectLines(mp, 3, m_bbi, index)) {
                    m_selectShape = m_showIndicator2
                }
            } else if ((m_showIndicator2 == "TRIX")) {
                if (selectLines(mp, 3, m_trix, index)) {
                    m_selectShape = m_showIndicator2
                    m_selectShapeEx = "TRIX"
                } else if (selectLines(mp, 3, m_trixMa, index)) {
                    m_selectShape = m_showIndicator2
                    m_selectShapeEx = "TRIXMA"
                }
            } else if ((m_showIndicator2 == "DMA")) {
                if (selectLines(mp, 3, m_dma1, index)) {
                    m_selectShape = m_showIndicator2
                    m_selectShapeEx = "DIF"
                } else if (selectLines(mp, 3, m_dma2, index)) {
                    m_selectShape = m_showIndicator2
                    m_selectShapeEx = "DIFMA"
                }
            }
        } else if (mp.y >= candleHeight + volHeight &&
            mp.y <= candleHeight + volHeight + indHeight
        ) {
            if ((m_showIndicator == "MACD")) {
                if (selectLines(mp, 2, m_allmacdarr, index)) {
                    m_selectShape = m_showIndicator
                    m_selectShapeEx = "MACD"
                }
                if (selectLines(mp, 2, m_alldifarr, index)) {
                    m_selectShape = m_showIndicator
                    m_selectShapeEx = "DIF"
                } else if (selectLines(mp, 2, m_alldeaarr, index)) {
                    m_selectShape = m_showIndicator
                    m_selectShapeEx = "DEA"
                }
            } else if ((m_showIndicator == "KDJ")) {
                if (selectLines(mp, 2, m_kdjK, index)) {
                    m_selectShape = m_showIndicator
                    m_selectShapeEx = "K"
                } else if (selectLines(mp, 2, m_kdjD, index)) {
                    m_selectShape = m_showIndicator
                    m_selectShapeEx = "D"
                } else if (selectLines(mp, 2, m_kdjJ, index)) {
                    m_selectShape = m_showIndicator
                    m_selectShapeEx = "J"
                }
            } else if ((m_showIndicator == "RSI")) {
                if (selectLines(mp, 2, m_rsi1, index)) {
                    m_selectShape = m_showIndicator
                    m_selectShapeEx = "6"
                } else if (selectLines(mp, 2, m_rsi2, index)) {
                    m_selectShape = m_showIndicator
                    m_selectShapeEx = "12"
                } else if (selectLines(mp, 2, m_rsi3, index)) {
                    m_selectShape = m_showIndicator
                    m_selectShapeEx = "24"
                }
            } else if ((m_showIndicator == "BIAS")) {
                if (selectLines(mp, 2, m_bias1, index)) {
                    m_selectShape = m_showIndicator
                    m_selectShapeEx = "1"
                } else if (selectLines(mp, 2, m_bias2, index)) {
                    m_selectShape = m_showIndicator
                    m_selectShapeEx = "2"
                } else if (selectLines(mp, 2, m_bias3, index)) {
                    m_selectShape = m_showIndicator
                    m_selectShapeEx = "3"
                }
            } else if ((m_showIndicator == "ROC")) {
                if (selectLines(mp, 2, m_roc, index)) {
                    m_selectShape = m_showIndicator
                    m_selectShapeEx = "ROC"
                } else if (selectLines(mp, 2, m_rocMa, index)) {
                    m_selectShape = m_showIndicator
                    m_selectShapeEx = "ROCMA"
                }
            } else if ((m_showIndicator == "WR")) {
                if (selectLines(mp, 2, m_wr1, index)) {
                    m_selectShape = m_showIndicator
                    m_selectShapeEx = "1"
                } else if (selectLines(mp, 2, m_wr2, index)) {
                    m_selectShape = "WR"
                    m_selectShapeEx = "2"
                }
            } else if ((m_showIndicator == "CCI")) {
                if (selectLines(mp, 2, m_cci, index)) {
                    m_selectShape = m_showIndicator
                }
            } else if ((m_showIndicator == "BBI")) {
                if (selectLines(mp, 2, m_bbi, index)) {
                    m_selectShape = m_showIndicator
                }
            } else if ((m_showIndicator == "TRIX")) {
                if (selectLines(mp, 2, m_trix, index)) {
                    m_selectShape = m_showIndicator
                    m_selectShapeEx = "TRIX"
                } else if (selectLines(mp, 2, m_trixMa, index)) {
                    m_selectShape = m_showIndicator
                    m_selectShapeEx = "TRIXMA"
                }
            } else if ((m_showIndicator == "DMA")) {
                if (selectLines(mp, 2, m_dma1, index)) {
                    m_selectShape = m_showIndicator
                    m_selectShapeEx = "DIF"
                } else if (selectLines(mp, 2, m_dma2, index)) {
                    m_selectShape = m_showIndicator
                    m_selectShapeEx = "DIFMA"
                }
            }
        } else if (mp.y >= candleHeight && mp.y <= candleHeight + volHeight) {
            val volY = getChartY(1, m_datas!![index].m_volume)
            val zeroY = getChartY(1, 0.0)
            if (mp.y >= Math.min(volY, zeroY) && mp.y <= Math.max(volY, zeroY)) {
                m_selectShape = "VOL"
            }
        } else if (mp.y >= 0 && mp.y <= candleHeight) {
            val isTrend = (m_cycle == "trend")
            if (!isTrend) {
                if ((m_mainIndicator == "BOLL")) {
                    if (selectLines(mp, 0, m_bollMid, index)) {
                        m_selectShape = m_mainIndicator
                        m_selectShapeEx = "MID"
                    } else if (selectLines(mp, 0, m_bollUp, index)) {
                        m_selectShape = m_mainIndicator
                        m_selectShapeEx = "UP"
                    } else if (selectLines(mp, 0, m_bollDown, index)) {
                        m_selectShape = m_mainIndicator
                        m_selectShapeEx = "DOWN"
                    }
                } else if ((m_mainIndicator == "MA")) {
                    if (selectLines(mp, 0, m_ma5, index)) {
                        m_selectShape = m_mainIndicator
                        (m_selectShapeEx == "5")
                    } else if (selectLines(mp, 0, m_ma10, index)) {
                        m_selectShape = m_mainIndicator
                        (m_selectShapeEx == "10")
                    } else if (selectLines(mp, 0, m_ma20, index)) {
                        m_selectShape = m_mainIndicator
                        (m_selectShapeEx == "20")
                    } else if (selectLines(mp, 0, m_ma30, index)) {
                        m_selectShape = m_mainIndicator
                        (m_selectShapeEx == "30")
                    } else if (selectLines(mp, 0, m_ma120, index)) {
                        m_selectShape = m_mainIndicator
                        (m_selectShapeEx == "120")
                    } else if (selectLines(mp, 0, m_ma250, index)) {
                        m_selectShape = m_mainIndicator
                        (m_selectShapeEx == "250")
                    }
                }
            }
            if ((m_selectShape == "")) {
                val highY = getChartY(0, m_datas!![index].m_high)
                val lowY = getChartY(0, m_datas!![index].m_low)
                if (isTrend) {
                    if (selectLines(mp, 0, m_closeArr, index)) {
                        m_selectShape = "CANDLE"
                    }
                } else {
                    if (mp.y >= Math.min(lowY, highY) && mp.y <= Math.max(lowY, highY)) {
                        m_selectShape = "CANDLE"
                    }
                }
            }
        }
        if (m_shapes.size > 0) {
            for (i in m_shapes.indices) {
                val shape = m_shapes[i]
                if (shape.m_leftOrRight) {
                    if (selectLines(mp, shape.m_divIndex, shape.m_datas, index)) {
                        m_selectShape = shape.m_shapeName
                        break
                    }
                } else {
                    if (selectLinesInRight(mp, shape.m_divIndex, shape.m_datas, index)) {
                        m_selectShape = shape.m_shapeName
                        break
                    }
                }
            }
        }
    }

    /**
     * 计算直线参数
     * @params x1 横坐标1
     * @params y1 纵坐标1
     * @params x2 横坐标2
     * @params y2 纵坐标2
     * @params x3 横坐标3
     * @params y3 纵坐标3
     */
    fun lineXY(x1: Double, y1: Double, x2: Double, y2: Double, oX: Double, oY: Double) {
        m_kChart = 0.0
        m_bChart = 0.0
        if ((x1 - oX) != (x2 - oX)) {
            m_kChart = ((y2 - oY) - (y1 - oY)) / ((x2 - oX) - (x1 - oX))
            m_bChart = (y1 - oY) - m_kChart * (x1 - oX)
        }
    }

    /**
     * 计算线性回归
     * @params list 集合
     */
    fun linearRegressionEquation(list: ArrayList<Double>): Double {
        val result = 0.0
        var sumX = 0.0
        var sumY = 0.0
        var sumUp = 0.0
        var sumDown = 0.0
        var xAvg = 0.0
        var yAvg = 0.0
        m_kChart = 0.0
        m_bChart = 0.0
        val length = list.size
        if (length > 1) {
            for (i in 0 until length) {
                sumX += (i + 1).toDouble()
                sumY += list[i]
            }
            xAvg = sumX / length
            yAvg = sumY / length
            for (i in 0 until length) {
                sumUp += (i + 1 - xAvg) * (list[i] - yAvg)
                sumDown += (i + 1 - xAvg) * (i + 1 - xAvg)
            }
            m_kChart = sumUp / sumDown
            m_bChart = yAvg - m_kChart * xAvg
        }
        return result
    }

    /**
     * 计算最小值
     * @params ticks 最高价数组
     * @params days 周期
     */
    fun llvValue(ticks: ArrayList<Double>, days: Int): ArrayList<Double> {
        val llv = ArrayList<Double>()
        var min = ticks[0]
        for (i in ticks.indices) {
            if (i >= days) {
                min = ticks[i]
                for (j in i downTo (i - days) + 1) {
                    if (min > ticks[j]) {
                        min = ticks[j]
                    }
                }
                llv.add(min)
            } else {
                if (min > ticks[i]) {
                    min = ticks[i]
                }
                llv.add(min)
            }
        }
        return llv
    }

    /**
     * 计算最大值
     * @params list 集合
     */
    fun maxValue(list: ArrayList<Double>): Double {
        val length = list.size
        var max = 0.0
        for (i in 0 until length) {
            if (i == 0) {
                max = list[i]
            } else {
                if (max < list[i]) {
                    max = list[i]
                }
            }
        }
        return max
    }

    /**
     * 计算最小值
     * @params list 集合
     */
    fun minValue(list: ArrayList<Double>): Double {
        val length = list.size
        var min = 0.0
        for (i in 0 until length) {
            if (i == 0) {
                min = list[i]
            } else {
                if (min > list[i]) {
                    min = list[i]
                }
            }
        }
        return min
    }

    /**
     * MA数据计算
     * @params ticks 最高价数组
     * @params days 周期
     */
    fun maValue(ticks: ArrayList<Double>, days: Int): ArrayList<Double> {
        var maSum = 0.0
        val mas = ArrayList<Double>()
        var last = 0.0
        for (i in ticks.indices) {
            var ma = 0.0
            if (i >= days) {
                last = ticks[i - days]
                maSum = maSum + ticks[i] - last
                ma = maSum / days
            } else {
                maSum += ticks[i]
                ma = maSum / (i + 1)
            }
            mas.add(ma)
        }
        return mas
    }

    /**
     * 绘图方法
     * @params paint 绘图对象
     * @params clipRect 裁剪区
     */
    override fun onPaint(paint: FCPaint, clipRect: FCRect) {
        super.onPaint(paint, clipRect)
        drawChartScale(paint, clipRect)
        drawChartStock(paint, clipRect)
        drawChartPlot(paint, clipRect)
        drawChartCrossLine(paint, clipRect)
    }

    /**
     * 触摸按下方法
     * @params touchInfo 触摸信息
     */
    override fun onTouchDown(touchInfo: FCTouchInfo) {
        super.onTouchDown(touchInfo)
        touchDownChart(
            touchInfo.m_firstTouch,
            touchInfo.m_firstPoint,
            touchInfo.m_secondTouch,
            touchInfo.m_secondPoint,
            touchInfo.m_clicks
        )
        invalidate()
    }

    /**
     * 触摸移动方法
     * @params touchInfo 触摸信息
     */
    override fun onTouchMove(touchInfo: FCTouchInfo) {
        super.onTouchMove(touchInfo)
        touchMoveChart(
            touchInfo.m_firstTouch,
            touchInfo.m_firstPoint,
            touchInfo.m_secondTouch,
            touchInfo.m_secondPoint
        )
        invalidate()
    }

    /**
     * 触摸离开方法
     * @params touchInfo 触摸信息
     */
    override fun onTouchLeave(touchInfo: FCTouchInfo) {
        super.onTouchLeave(touchInfo)
        invalidate()
    }

    /**
     * 触摸抬起方法
     * @params touchInfo 触摸信息
     */
    override fun onTouchUp(touchInfo: FCTouchInfo) {
        super.onTouchUp(touchInfo)
        m_firstTouchIndexCache = -1
        m_secondTouchIndexCache = -1
        invalidate()
    }

    /**
     * 触摸滚动方法
     * @params touchInfo 触摸信息
     */
    override fun onTouchWheel(touchInfo: FCTouchInfo) {
        super.onTouchWheel(touchInfo)
        if (touchInfo.m_delta > 0) {
            zoomOutChart()
        } else if (touchInfo.m_delta < 0) {
            zoomInChart()
        }
        invalidate()
    }

    /**
     * 键盘按下方法
     * @params key 按键
     */
    override fun onKeyDown(key: Char) {
        super.onKeyDown(key)
        keyDownChart(key)
        invalidate()
    }

    /**
     * 计算平行四边形参数
     * @params x1 横坐标1
     * @params y1 纵坐标1
     * @params x2 横坐标2
     * @params y2 纵坐标2
     * @params x3 横坐标3
     * @params y3 纵坐标3
     */
    fun parallelogram(x1: Double, y1: Double, x2: Double, y2: Double, x3: Double, y3: Double) {
        m_x4Chart = x1 + x3 - x2
        m_y4Chart = y1 + y3 - y2
    }

    /**
     * 根据坐标计算矩形
     * @params x1 横坐标1
     * @params y1 纵坐标1
     * @params x2 横坐标2
     * @params y2 纵坐标2
     */
    fun rectangleXYWH(x1: Double, y1: Double, x2: Double, y2: Double) {
        m_xChart = if (x1 < x2) x1 else x2
        m_yChart = if (y1 < y2) y1 else y2
        m_wChart = if (x1 - x2 > 0) x1 - x2 else x2 - x1
        m_hChart = if (y1 - y2 > 0) y1 - y2 else y2 - y1
        if (m_wChart <= 0) {
            m_wChart = 4.0
        }
        if (m_hChart <= 0) {
            m_hChart = 4.0
        }
    }

    /**
     * 自动设置首先可见和最后可见的记录号
     */
    fun resetChartVisibleRecord() {
        val rowsCount = m_datas!!.size
        val workingAreaWidth = chartWorkAreaWidth.toDouble()
        if (m_autoFillHScale) {
            if (workingAreaWidth > 0 && rowsCount > 0) {
                m_hScalePixel = workingAreaWidth / rowsCount
                m_firstVisibleIndex = 0
                m_lastVisibleIndex = rowsCount - 1
            }
        } else {
            val maxVisibleRecord = getChartMaxVisibleCount(m_hScalePixel, workingAreaWidth)
            //没数据时重置
            if (rowsCount == 0) {
                m_firstVisibleIndex = -1
                m_lastVisibleIndex = -1
            } else {
                //数据不足一屏时
                if (rowsCount < maxVisibleRecord) {
                    m_lastVisibleIndex = rowsCount - 1
                    m_firstVisibleIndex = 0
                } else {
                    //显示中间的数据时
                    if (((m_firstVisibleIndex != -1) && (
                                m_lastVisibleIndex != -1) &&
                                !m_lastRecordIsVisible)
                    ) {
                        val index = getChartIndexByDate(m_lastVisibleKey)
                        if (index != -1) {
                            m_lastVisibleIndex = index
                        }
                        m_firstVisibleIndex = m_lastVisibleIndex - maxVisibleRecord + 1
                        if (m_firstVisibleIndex < 0) {
                            m_firstVisibleIndex = 0
                            m_lastVisibleIndex = m_firstVisibleIndex + maxVisibleRecord
                            checkChartLastVisibleIndex()
                        }
                    } else {
                        //第一条或最后一条数据被显示时
                        m_lastVisibleIndex = rowsCount - 1
                        m_firstVisibleIndex = m_lastVisibleIndex - maxVisibleRecord + 1
                        if (m_firstVisibleIndex > m_lastVisibleIndex) {
                            m_firstVisibleIndex = m_lastVisibleIndex
                        }
                    }
                }
            }
        }
    }

    /**
     * REF函数
     * @params ticks 数据
     * @params days 日期
     */
    fun refValue(ticks: ArrayList<Double>, days: Int): ArrayList<Double> {
        val refArr = ArrayList<Double>()
        val length = ticks.size
        for (i in 0 until length) {
            var refV = 0.0
            if (i >= days) {
                refV = ticks[i - days]
            } else {
                refV = ticks[0]
            }
            refArr.add(refV)
        }
        return refArr
    }

    /**
     * 判断是否选中直线
     * @params mp 坐标
     * @params x1 横坐标1
     * @params y1 纵坐标1
     * @params x2 横坐标2
     * @params y2 纵坐标2
     */
    fun selectLine(mp: FCPoint, x1: Double, y1: Double, x2: Double, y2: Double): Boolean {
        lineXY(x1, y1, x2, y2, 0.0, 0.0)
        if (!(m_kChart == 0.0 && m_bChart == 0.0)) {
            if (mp.y / (mp.x * m_kChart + m_bChart) >= 0.9 &&
                mp.y / (mp.x * m_kChart + m_bChart) <= 1.1
            ) {
                return true
            }
        } else {
            if (mp.x >= x1 - m_plotPointSizeChart &&
                mp.x <= x1 + m_plotPointSizeChart
            ) {
                return true
            }
        }
        return false
    }

    /**
     * 判断是否选中射线
     * @params mp 坐标
     * @params x1 横坐标1
     * @params y1 纵坐标1
     * @params x2 横坐标2
     * @params y2 纵坐标2
     */
    fun selectRay(mp: FCPoint, x1: Double, y1: Double, x2: Double, y2: Double): Boolean {
        lineXY(x1, y1, x2, y2, 0.0, 0.0)
        if (!(m_kChart == 0.0 && m_bChart == 0.0)) {
            if (mp.y / (mp.x * m_kChart + m_bChart) >= 0.9 &&
                mp.y / (mp.x * m_kChart + m_bChart) <= 1.1
            ) {
                if (x1 >= x2) {
                    if (mp.x > x1 + m_plotPointSizeChart) {
                        return false
                    }
                } else if (x1 < x2) {
                    if (mp.x < x1 - m_plotPointSizeChart) {
                        return false
                    }
                }
                return true
            }
        } else {
            if (mp.x >= x1 - m_plotPointSizeChart &&
                mp.x <= x1 + m_plotPointSizeChart
            ) {
                if (y1 >= y2) {
                    if (mp.y <= y1 - m_plotPointSizeChart) {
                        return true
                    }
                } else {
                    if (mp.y >= y1 - m_plotPointSizeChart) {
                        return true
                    }
                }
            }
        }
        return false
    }

    /**
     * 判断是否选中线段
     * @params mp 坐标
     * @params x1 横坐标1
     * @params y1 纵坐标1
     * @params x2 横坐标2
     * @params y2 纵坐标2
     */
    fun selectSegment(mp: FCPoint, x1: Double, y1: Double, x2: Double, y2: Double): Boolean {
        lineXY(x1, y1, x2, y2, 0.0, 0.0)
        val smallX = if (x1 <= x2) x1 else x2
        val smallY = if (y1 <= y2) y1 else y2
        val bigX = if (x1 > x2) x1 else x2
        val bigY = if (y1 > y2) y1 else y2
        if ((mp.x >= smallX - 2) && (
                    mp.x <= bigX + 2) && (
                    mp.y >= smallY - 2) && (
                    mp.y <= bigY + 2)
        ) {
            if (m_kChart != 0.0 || m_bChart != 0.0) {
                if (mp.y / (mp.x * m_kChart + m_bChart) >= 0.9 &&
                    mp.y / (mp.x * m_kChart + m_bChart) <= 1.1
                ) {
                    return true
                }
            } else {
                if (mp.x >= x1 - m_plotPointSizeChart &&
                    mp.x <= x1 + m_plotPointSizeChart
                ) {
                    return true
                }
            }
        }
        return false
    }

    /**
     * 获取方差数据
     */
    fun standardDeviationSum(listValue: ArrayList<Double>, avgValue: Double): Double {
        val targetValue = listValue[listValue.size - 1]
        var sumValue = (targetValue - avgValue) * (targetValue - avgValue)
        for (i in 0 until (listValue.size - 1)) {
            val ileft = listValue[i]
            sumValue = sumValue + (ileft - avgValue) * (ileft - avgValue)
        }
        return sumValue
    }

    /**
     * 选中画线
     * @params mp 坐标
     */
    fun selectPlot(mp: FCPoint): FCPlot? {
        var sPlot: FCPlot? = null
        m_startMovePlot = false
        m_selectPlotPoint = -1
        for (i in m_plots.indices) {
            val plot = m_plots[i]
            var index1 = 0
            var index2 = 0
            var index3 = 0
            var mpx1 = 0
            var mpy1 = 0
            var mpx2 = 0
            var mpy2 = 0
            var mpx3 = 0
            var mpy3 = 0
            //检查关键点
            if (plot.m_key1 > 0) {
                index1 = getChartIndexByDate(plot.m_key1)
                mpx1 = getChartX(index1)
                mpy1 = getChartY(0, plot.m_value1)
                if ((mp.x >= mpx1 - m_plotPointSizeChart) && (
                            mp.x <= mpx1 + m_plotPointSizeChart) && (
                            mp.y >= mpy1 - m_plotPointSizeChart) && (
                            mp.y <= mpy1 + m_plotPointSizeChart)
                ) {
                    sPlot = plot
                    m_selectPlotPoint = 0
                    break
                }
            }
            if (plot.m_key2 > 0) {
                index2 = getChartIndexByDate(plot.m_key2)
                mpx2 = getChartX(index2)
                mpy2 = getChartY(0, plot.m_value2)
                if ((mp.x >= mpx2 - m_plotPointSizeChart) && (
                            mp.x <= mpx2 + m_plotPointSizeChart) && (
                            mp.y >= mpy2 - m_plotPointSizeChart) && (
                            mp.y <= mpy2 + m_plotPointSizeChart)
                ) {
                    sPlot = plot
                    m_selectPlotPoint = 1
                    break
                }
            }
            if (plot.m_key3 > 0) {
                index3 = getChartIndexByDate(plot.m_key3)
                mpx3 = getChartX(index3)
                mpy3 = getChartY(0, plot.m_value3)
                if ((mp.x >= mpx3 - m_plotPointSizeChart) && (
                            mp.x <= mpx3 + m_plotPointSizeChart) && (
                            mp.y >= mpy3 - m_plotPointSizeChart) && (
                            mp.y <= mpy3 + m_plotPointSizeChart)
                ) {
                    sPlot = plot
                    m_selectPlotPoint = 2
                    break
                }
            }
            //判断其余部分的选中
            if (m_selectPlotPoint == -1) {
                if ((plot.m_plotType == "Line")) {
                    m_startMovePlot = selectLine(
                        mp,
                        mpx1.toDouble(),
                        mpy1.toDouble(),
                        mpx2.toDouble(),
                        mpy2.toDouble()
                    )
                } else if ((plot.m_plotType == "ArrowSegment")) {
                    m_startMovePlot = selectSegment(
                        mp,
                        mpx1.toDouble(),
                        mpy1.toDouble(),
                        mpx2.toDouble(),
                        mpy2.toDouble()
                    )
                } else if ((plot.m_plotType == "AngleLine")) {
                    m_startMovePlot = selectLine(
                        mp,
                        mpx1.toDouble(),
                        mpy1.toDouble(),
                        mpx2.toDouble(),
                        mpy2.toDouble()
                    )
                    if (!m_startMovePlot) {
                        m_startMovePlot = selectLine(
                            mp,
                            mpx1.toDouble(),
                            mpy1.toDouble(),
                            mpx3.toDouble(),
                            mpy3.toDouble()
                        )
                    }
                } else if ((plot.m_plotType == "Parallel")) {
                    m_startMovePlot = selectLine(
                        mp,
                        mpx1.toDouble(),
                        mpy1.toDouble(),
                        mpx2.toDouble(),
                        mpy2.toDouble()
                    )
                    if (!m_startMovePlot) {
                        lineXY(
                            mpx1.toDouble(),
                            mpy1.toDouble(),
                            mpx2.toDouble(),
                            mpy2.toDouble(),
                            0.0,
                            0.0
                        )
                        val newB = mpy3 - m_kChart * mpx3
                        if (mpx2 == mpx1) {
                            if (mp.x >= mpx3 - m_plotPointSizeChart &&
                                mp.x <= mpx3 + m_plotPointSizeChart
                            ) {
                                m_startMovePlot = true
                            }
                        } else {
                            val newX1 = m_leftVScaleWidth.toDouble()
                            val newY1 = newX1 * m_kChart + newB
                            val newX2 = (size.cx - m_rightVScaleWidth).toDouble()
                            val newY2 = newX2 * m_kChart + newB
                            m_startMovePlot = selectLine(mp, newX1, newY1, newX2, newY2)
                        }
                    }
                } else if ((plot.m_plotType == "LRLine")) {
                    m_startMovePlot = selectSegment(
                        mp,
                        mpx1.toDouble(),
                        mpy1.toDouble(),
                        mpx2.toDouble(),
                        mpy2.toDouble()
                    )
                } else if ((plot.m_plotType == "Segment")) {
                    m_startMovePlot = selectSegment(
                        mp,
                        mpx1.toDouble(),
                        mpy1.toDouble(),
                        mpx2.toDouble(),
                        mpy2.toDouble()
                    )
                } else if ((plot.m_plotType == "Ray")) {
                    m_startMovePlot = selectRay(
                        mp,
                        mpx1.toDouble(),
                        mpy1.toDouble(),
                        mpx2.toDouble(),
                        mpy2.toDouble()
                    )
                } else if ((plot.m_plotType == "Triangle")) {
                    m_startMovePlot = selectSegment(
                        mp,
                        mpx1.toDouble(),
                        mpy1.toDouble(),
                        mpx2.toDouble(),
                        mpy2.toDouble()
                    )
                    if (!m_startMovePlot) {
                        m_startMovePlot = selectSegment(
                            mp,
                            mpx2.toDouble(),
                            mpy2.toDouble(),
                            mpx3.toDouble(),
                            mpy3.toDouble()
                        )
                    }
                    if (!m_startMovePlot) {
                        m_startMovePlot = selectSegment(
                            mp,
                            mpx1.toDouble(),
                            mpy1.toDouble(),
                            mpx3.toDouble(),
                            mpy3.toDouble()
                        )
                    }
                } else if ((plot.m_plotType == "SymmetricTriangle")) {
                    if (mpx2 != mpx1) {
                        val a = (mpy2 - mpy1).toDouble() / (mpx2 - mpx1).toDouble()
                        val b = mpy1 - a * mpx1
                        val c = -a
                        val d = mpy3 - c * mpx3
                        val leftX = m_leftVScaleWidth.toDouble()
                        var leftY = leftX * a + b
                        val rightX = (size.cx - m_rightVScaleWidth).toDouble()
                        var rightY = rightX * a + b
                        m_startMovePlot = selectSegment(mp, leftX, leftY, rightX, rightY)
                        if (!m_startMovePlot) {
                            leftY = leftX * c + d
                            rightY = rightX * c + d
                            m_startMovePlot = selectSegment(mp, leftX, leftY, rightX, rightY)
                        }
                    } else {
                        val divHeight = candleDivHeight.toDouble()
                        m_startMovePlot =
                            selectSegment(mp, mpx1.toDouble(), 0.0, mpx1.toDouble(), divHeight)
                        if (!m_startMovePlot) {
                            m_startMovePlot =
                                selectSegment(mp, mpx3.toDouble(), 0.0, mpx3.toDouble(), divHeight)
                        }
                    }
                } else if ((plot.m_plotType == "Rect")) {
                    val sX1 = Math.min(mpx1, mpx2)
                    val sY1 = Math.min(mpy1, mpy2)
                    val sX2 = Math.max(mpx1, mpx2)
                    val sY2 = Math.max(mpy1, mpy2)
                    m_startMovePlot = selectSegment(
                        mp,
                        sX1.toDouble(),
                        sY1.toDouble(),
                        sX2.toDouble(),
                        sY1.toDouble()
                    )
                    if (!m_startMovePlot) {
                        m_startMovePlot = selectSegment(
                            mp,
                            sX2.toDouble(),
                            sY1.toDouble(),
                            sX2.toDouble(),
                            sY2.toDouble()
                        )
                    }
                    if (!m_startMovePlot) {
                        m_startMovePlot = selectSegment(
                            mp,
                            sX1.toDouble(),
                            sY2.toDouble(),
                            sX2.toDouble(),
                            sY2.toDouble()
                        )
                    }
                    if (!m_startMovePlot) {
                        m_startMovePlot = selectSegment(
                            mp,
                            sX1.toDouble(),
                            sY1.toDouble(),
                            sX1.toDouble(),
                            sY2.toDouble()
                        )
                    }
                } else if ((plot.m_plotType == "BoxLine")) {
                    val sX1 = Math.min(mpx1, mpx2)
                    val sY1 = Math.min(mpy1, mpy2)
                    val sX2 = Math.max(mpx1, mpx2)
                    val sY2 = Math.max(mpy1, mpy2)
                    m_startMovePlot = selectSegment(
                        mp,
                        sX1.toDouble(),
                        sY1.toDouble(),
                        sX2.toDouble(),
                        sY1.toDouble()
                    )
                    if (!m_startMovePlot) {
                        m_startMovePlot = selectSegment(
                            mp,
                            sX2.toDouble(),
                            sY1.toDouble(),
                            sX2.toDouble(),
                            sY2.toDouble()
                        )
                    }
                    if (!m_startMovePlot) {
                        m_startMovePlot = selectSegment(
                            mp,
                            sX1.toDouble(),
                            sY2.toDouble(),
                            sX2.toDouble(),
                            sY2.toDouble()
                        )
                    }
                    if (!m_startMovePlot) {
                        m_startMovePlot = selectSegment(
                            mp,
                            sX1.toDouble(),
                            sY1.toDouble(),
                            sX1.toDouble(),
                            sY2.toDouble()
                        )
                    }
                } else if ((plot.m_plotType == "TironeLevels")) {
                    val sX1 = Math.min(mpx1, mpx2)
                    val sY1 = Math.min(mpy1, mpy2)
                    val sX2 = Math.max(mpx1, mpx2)
                    val sY2 = Math.max(mpy1, mpy2)
                    m_startMovePlot = selectSegment(
                        mp,
                        sX1.toDouble(),
                        sY1.toDouble(),
                        sX2.toDouble(),
                        sY1.toDouble()
                    )
                    if (!m_startMovePlot) {
                        m_startMovePlot = selectSegment(
                            mp,
                            sX1.toDouble(),
                            sY2.toDouble(),
                            sX2.toDouble(),
                            sY2.toDouble()
                        )
                    }
                } else if ((plot.m_plotType == "QuadrantLines")) {
                    val sX1 = Math.min(mpx1, mpx2)
                    val sY1 = Math.min(mpy1, mpy2)
                    val sX2 = Math.max(mpx1, mpx2)
                    val sY2 = Math.max(mpy1, mpy2)
                    m_startMovePlot = selectSegment(
                        mp,
                        sX1.toDouble(),
                        sY1.toDouble(),
                        sX2.toDouble(),
                        sY1.toDouble()
                    )
                    if (!m_startMovePlot) {
                        m_startMovePlot = selectSegment(
                            mp,
                            sX1.toDouble(),
                            sY2.toDouble(),
                            sX2.toDouble(),
                            sY2.toDouble()
                        )
                    }
                } else if ((plot.m_plotType == "GoldenRatio")) {
                    val sY1 = Math.min(mpy1, mpy2)
                    val sY2 = Math.max(mpy1, mpy2)
                    val ranges = ArrayList<Double>()
                    ranges.add(0.0)
                    ranges.add(0.236)
                    ranges.add(0.382)
                    ranges.add(0.5)
                    ranges.add(0.618)
                    ranges.add(0.809)
                    ranges.add(1.0)
                    ranges.add(1.382)
                    ranges.add(1.618)
                    ranges.add(2.0)
                    ranges.add(2.382)
                    ranges.add(2.618)
                    for (j in ranges.indices) {
                        val newY =
                            if (sY1 <= sY2) sY1 + (sY2 - sY1) * ranges[j] else sY2 + (sY1 - sY2) * (1 - ranges[j])
                        m_startMovePlot = selectSegment(
                            mp, m_leftVScaleWidth.toDouble(),
                            newY, (size.cx - m_rightVScaleWidth).toDouble(), newY
                        )
                        if (m_startMovePlot) {
                            break
                        }
                    }
                } else if ((plot.m_plotType == "Cycle")) {
                    val r = Math.sqrt(
                        Math.abs((mpx2 - mpx1) * (mpx2 - mpx1) + (mpy2 - mpy1) * (mpy2 - mpy1))
                            .toDouble()
                    )
                    val round =
                        ((mp.x - mpx1) * (mp.x - mpx1) + (mp.y - mpy1) * (mp.y - mpy1)).toDouble()
                    if (round / (r * r) >= 0.9 && round / (r * r) <= 1.1) {
                        m_startMovePlot = true
                    }
                } else if ((plot.m_plotType == "CircumCycle")) {
                    ellipseOR(
                        mpx1.toDouble(),
                        mpy1.toDouble(),
                        mpx2.toDouble(),
                        mpy2.toDouble(),
                        mpx3.toDouble(),
                        mpy3.toDouble()
                    )
                    val round = (mp.x - m_oXChart) * (mp.x - m_oXChart) +
                            (mp.y - m_oYChart) * (mp.y - m_oYChart)
                    if (round / (m_rChart * m_rChart) >= 0.9 &&
                        round / (m_rChart * m_rChart) <= 1.1
                    ) {
                        m_startMovePlot = true
                    }
                } else if ((plot.m_plotType == "Ellipse")) {
                    var x1 = 0.0
                    var y1 = 0.0
                    var x2 = 0.0
                    var y2 = 0.0
                    if (mpx1 <= mpx2) {
                        x1 = mpx2.toDouble()
                        y1 = mpy2.toDouble()
                        x2 = mpx1.toDouble()
                        y2 = mpy1.toDouble()
                    } else {
                        x1 = mpx1.toDouble()
                        y1 = mpy1.toDouble()
                        x2 = mpx2.toDouble()
                        y2 = mpy2.toDouble()
                    }
                    val x = x1 - (x1 - x2)
                    var y = 0.0
                    val width = (x1 - x2) * 2
                    var height = 0.0
                    if (y1 >= y2) {
                        height = (y1 - y2) * 2
                    } else {
                        height = (y2 - y1) * 2
                    }
                    y = y2 - height / 2
                    val a = width / 2
                    val b = height / 2
                    m_startMovePlot = ellipseHasPoint(
                        mp.x.toDouble(), mp.y.toDouble(), x + (width / 2), y + (height / 2), a, b
                    )
                } else if ((plot.m_plotType == "LRBand")) {
                    m_startMovePlot = selectSegment(
                        mp,
                        mpx1.toDouble(),
                        mpy1.toDouble(),
                        mpx2.toDouble(),
                        mpy2.toDouble()
                    )
                    if (!m_startMovePlot) {
                        val list = ArrayList<Double>()
                        val minIndex = Math.min(index1, index2)
                        val maxIndex = Math.max(index1, index2)
                        for (j in minIndex..maxIndex) {
                            list.add(m_datas!![j].m_close)
                        }
                        linearRegressionEquation(list)
                        getLRBandRange(plot, m_kChart, m_bChart)
                        mpy1 = getChartY(0, plot.m_value1 + m_upSubValue)
                        mpy2 = getChartY(0, plot.m_value2 + m_upSubValue)
                        m_startMovePlot = selectSegment(
                            mp,
                            mpx1.toDouble(),
                            mpy1.toDouble(),
                            mpx2.toDouble(),
                            mpy2.toDouble()
                        )
                        if (!m_startMovePlot) {
                            mpy1 = getChartY(0, plot.m_value1 - m_downSubValue)
                            mpy2 = getChartY(0, plot.m_value2 - m_downSubValue)
                            m_startMovePlot = selectSegment(
                                mp,
                                mpx1.toDouble(),
                                mpy1.toDouble(),
                                mpx2.toDouble(),
                                mpy2.toDouble()
                            )
                        }
                    }
                } else if ((plot.m_plotType == "LRChannel")) {
                    lineXY(
                        mpx1.toDouble(),
                        mpy1.toDouble(),
                        mpx2.toDouble(),
                        mpy2.toDouble(),
                        0.0,
                        0.0
                    )
                    val rightX = (size.cx - m_rightVScaleWidth).toDouble()
                    var rightY = rightX * m_kChart + m_bChart
                    m_startMovePlot =
                        selectSegment(mp, mpx1.toDouble(), mpy1.toDouble(), rightX, rightY)
                    if (!m_startMovePlot) {
                        val list = ArrayList<Double>()
                        val minIndex = Math.min(index1, index2)
                        val maxIndex = Math.max(index1, index2)
                        for (j in minIndex..maxIndex) {
                            list.add(m_datas!![j].m_close)
                        }
                        linearRegressionEquation(list)
                        getLRBandRange(plot, m_kChart, m_bChart)
                        mpy1 = getChartY(0, plot.m_value1 + m_upSubValue)
                        mpy2 = getChartY(0, plot.m_value2 + m_upSubValue)
                        lineXY(
                            mpx1.toDouble(),
                            mpy1.toDouble(),
                            mpx2.toDouble(),
                            mpy2.toDouble(),
                            0.0,
                            0.0
                        )
                        rightY = rightX * m_kChart + m_bChart
                        m_startMovePlot =
                            selectSegment(mp, mpx1.toDouble(), mpy1.toDouble(), rightX, rightY)
                        if (!m_startMovePlot) {
                            mpy1 = getChartY(0, plot.m_value1 - m_downSubValue)
                            mpy2 = getChartY(0, plot.m_value2 - m_downSubValue)
                            lineXY(
                                mpx1.toDouble(),
                                mpy1.toDouble(),
                                mpx2.toDouble(),
                                mpy2.toDouble(),
                                0.0,
                                0.0
                            )
                            rightY = rightX * m_kChart + m_bChart
                            m_startMovePlot =
                                selectSegment(mp, mpx1.toDouble(), mpy1.toDouble(), rightX, rightY)
                        }
                    }
                } else if ((plot.m_plotType == "ParalleGram")) {
                    parallelogram(
                        mpx1.toDouble(),
                        mpy1.toDouble(),
                        mpx2.toDouble(),
                        mpy2.toDouble(),
                        mpx3.toDouble(),
                        mpy3.toDouble()
                    )
                    m_startMovePlot = selectSegment(
                        mp,
                        mpx1.toDouble(),
                        mpy1.toDouble(),
                        mpx2.toDouble(),
                        mpy2.toDouble()
                    )
                    if (!m_startMovePlot) {
                        m_startMovePlot = selectSegment(
                            mp,
                            mpx2.toDouble(),
                            mpy2.toDouble(),
                            mpx3.toDouble(),
                            mpy3.toDouble()
                        )
                        if (!m_startMovePlot) {
                            m_startMovePlot = selectSegment(
                                mp,
                                mpx3.toDouble(),
                                mpy3.toDouble(),
                                m_x4Chart,
                                m_y4Chart
                            )
                            if (!m_startMovePlot) {
                                m_startMovePlot = selectSegment(
                                    mp,
                                    m_x4Chart,
                                    m_y4Chart,
                                    mpx1.toDouble(),
                                    mpy1.toDouble()
                                )
                            }
                        }
                    }
                } else if ((plot.m_plotType == "SpeedResist")) {
                    m_startMovePlot = selectSegment(
                        mp,
                        mpx1.toDouble(),
                        mpy1.toDouble(),
                        mpx2.toDouble(),
                        mpy2.toDouble()
                    )
                    if (!m_startMovePlot) {
                        if (mpx1 != mpx2 && mpy1 != mpy2) {
                            val firstP = FCPoint(mpx2, (mpy2 - (mpy2 - mpy1) / 3))
                            val secondP = FCPoint(mpx2, (mpy2 - (mpy2 - mpy1) * 2 / 3))
                            val startP = FCPoint(mpx1, mpy1)
                            var fK = 0.0
                            var fB = 0.0
                            var sK = 0.0
                            var sB = 0.0
                            lineXY(
                                startP.x.toDouble(),
                                startP.y.toDouble(),
                                firstP.x.toDouble(),
                                firstP.y.toDouble(),
                                0.0,
                                0.0
                            )
                            fK = m_kChart
                            fB = m_bChart
                            lineXY(
                                startP.x.toDouble(),
                                startP.y.toDouble(),
                                secondP.x.toDouble(),
                                secondP.y.toDouble(),
                                0.0,
                                0.0
                            )
                            sK = m_kChart
                            sB = m_bChart
                            var newYF = 0.0
                            var newYS = 0.0
                            var newX = 0.0
                            if (mpx2 > mpx1) {
                                newYF = fK * (size.cx - m_rightVScaleWidth) + fB
                                newYS = sK * (size.cx - m_rightVScaleWidth) + sB
                                newX = (size.cx - m_rightVScaleWidth).toDouble()
                            } else {
                                newYF = fB
                                newYS = sB
                                newX = m_leftVScaleWidth.toDouble()
                            }
                            m_startMovePlot = selectSegment(
                                mp,
                                startP.x.toDouble(),
                                startP.y.toDouble(),
                                newX,
                                newYF
                            )
                            if (!m_startMovePlot) {
                                m_startMovePlot = selectSegment(
                                    mp,
                                    startP.x.toDouble(),
                                    startP.y.toDouble(),
                                    newX,
                                    newYS
                                )
                            }
                        }
                    }
                } else if ((plot.m_plotType == "FiboFanline")) {
                    m_startMovePlot = selectSegment(
                        mp,
                        mpx1.toDouble(),
                        mpy1.toDouble(),
                        mpx2.toDouble(),
                        mpy2.toDouble()
                    )
                    if (!m_startMovePlot) {
                        if (mpx1 != mpx2 && mpy1 != mpy2) {
                            val firstP = FCPoint(mpx2, (mpy2 - (mpy2 - mpy1) * 0.382).toInt())
                            val secondP = FCPoint(mpx2, (mpy2 - (mpy2 - mpy1) * 0.5).toInt())
                            val thirdP = FCPoint(mpx2, (mpy2 - (mpy2 - mpy1) * 0.618).toInt())
                            val startP = FCPoint(mpx1, mpy1)
                            val listP = ArrayList<FCPoint>()
                            listP.add(firstP)
                            listP.add(secondP)
                            listP.add(thirdP)
                            val listSize = listP.size
                            for (j in 0 until listSize) {
                                lineXY(
                                    startP.x.toDouble(),
                                    startP.y.toDouble(),
                                    listP[j].x.toDouble(),
                                    listP[j].y.toDouble(),
                                    0.0,
                                    0.0
                                )
                                var newX = 0.0
                                var newY = 0.0
                                if (mpx2 > mpx1) {
                                    newY = m_kChart * (size.cx - m_rightVScaleWidth) +
                                            m_bChart
                                    newX = (size.cx - m_rightVScaleWidth).toDouble()
                                } else {
                                    newY = m_bChart
                                    newX = m_leftVScaleWidth.toDouble()
                                }
                                m_startMovePlot = selectSegment(
                                    mp,
                                    startP.x.toDouble(),
                                    startP.y.toDouble(),
                                    newX,
                                    newY
                                )
                                if (m_startMovePlot) {
                                    break
                                }
                            }
                        }
                    }
                } else if ((plot.m_plotType == "FiboTimezone")) {
                    var fValue = 1
                    val aIndex = index1
                    var pos = 1
                    val divHeight = candleDivHeight
                    m_startMovePlot = selectSegment(
                        mp,
                        mpx1.toDouble(),
                        0.0,
                        mpx1.toDouble(),
                        divHeight.toDouble()
                    )
                    if (!m_startMovePlot) {
                        while (aIndex + fValue <= m_lastVisibleIndex) {
                            fValue = fibonacciValue(pos)
                            val newIndex = aIndex + fValue
                            val newX = getChartX(newIndex)
                            m_startMovePlot = selectSegment(
                                mp,
                                newX.toDouble(),
                                0.0,
                                newX.toDouble(),
                                divHeight.toDouble()
                            )
                            if (m_startMovePlot) {
                                break
                            }
                            pos++
                        }
                    }
                } else if ((plot.m_plotType == "Percent")) {
                    val list = getPercentParams(mpy1.toDouble(), mpy2.toDouble())
                    for (j in list.indices) {
                        m_startMovePlot = selectSegment(
                            mp,
                            m_leftVScaleWidth.toDouble(),
                            list[j].toDouble(),
                            (size.cx - m_rightVScaleWidth).toDouble(),
                            list[j].toDouble()
                        )
                        if (m_startMovePlot) {
                            break
                        }
                    }
                }
                if (m_startMovePlot) {
                    sPlot = plot
                    plot.m_startKey1 = plot.m_key1
                    plot.m_startValue1 = plot.m_value1
                    plot.m_startKey2 = plot.m_key2
                    plot.m_startValue2 = plot.m_value2
                    plot.m_startKey3 = plot.m_key3
                    plot.m_startValue3 = plot.m_value3
                    break
                }
            }
        }
        return sPlot
    }

    /**
     * 设置可见索引
     * @params firstVisibleIndex 起始索引
     * @params lastVisibleIndex 结束索引
     */
    fun setChartVisibleIndex(firstVisibleIndex: Int, lastVisibleIndex: Int) {
        val xScalePixel =
            (chartWorkAreaWidth / (lastVisibleIndex - firstVisibleIndex + 1)).toDouble()
        if (xScalePixel < 1000000) {
            m_firstVisibleIndex = firstVisibleIndex
            m_lastVisibleIndex = lastVisibleIndex
            //设置最后一条记录是否可见
            if (lastVisibleIndex != m_datas!!.size - 1) {
                m_lastRecordIsVisible = false
            } else {
                m_lastRecordIsVisible = true
            }
            m_hScalePixel = xScalePixel
            checkChartLastVisibleIndex()
        }
    }

    /**
     * 判断是否选中线条
     * @params mp 坐标
     * @params divIndex 层索引
     * @params datas 数据
     * @params curIndex 当前索引
     */
    fun selectLines(mp: FCPoint, divIndex: Int, datas: ArrayList<Double>, curIndex: Int): Boolean {
        if (datas.size > 0) {
            val topY = getChartY(divIndex, datas[curIndex])
            if (m_hScalePixel <= 1) {
                if (mp.y >= topY - 8 && mp.y <= topY + 8) {
                    return true
                }
            } else {
                val index = curIndex
                val scaleX = getChartX(index)
                var judgeTop = 0.0
                var judgeScaleX = scaleX.toDouble()
                if (mp.x >= scaleX) {
                    val leftIndex = curIndex + 1
                    if (curIndex < m_lastVisibleIndex) {
                        val rightValue = datas[leftIndex]
                        judgeTop = getChartY(divIndex, rightValue).toDouble()
                    } else {
                        judgeTop = topY.toDouble()
                    }
                } else {
                    judgeScaleX = scaleX - m_hScalePixel
                    val rightIndex = curIndex - 1
                    if (curIndex > 0) {
                        val leftValue = datas[rightIndex]
                        judgeTop = getChartY(divIndex, leftValue).toDouble()
                    } else {
                        judgeTop = topY.toDouble()
                    }
                }
                val lineWidth = 4.0
                var judgeX = 0.0
                var judgeY = 0.0
                var judgeW = 0.0
                var judgeH = 0.0
                if (judgeTop >= topY) {
                    judgeX = judgeScaleX
                    judgeY = topY - 2 - lineWidth
                    judgeW = m_hScalePixel
                    judgeH =
                        if (judgeTop - topY + lineWidth < 4) 4.0 else (judgeTop - topY) + 4 + lineWidth
                } else {
                    judgeX = judgeScaleX
                    judgeY = judgeTop - 2 - (lineWidth / 2)
                    judgeW = m_hScalePixel
                    judgeH =
                        if (topY - judgeTop + lineWidth < 4) 4.0 else (topY - judgeTop) + 4 + lineWidth
                }
                if ((mp.x >= judgeX) && (
                            mp.x <= judgeX + judgeW) && (
                            mp.y >= judgeY) && (
                            mp.y <= judgeY + judgeH)
                ) {
                    return true
                }
            }
        }
        return false
    }

    /**
     * 判断是否在右轴选中线条
     * @params mp 坐标
     * @params divIndex 层索引
     * @params datas 数据
     * @params curIndex 当前索引
     */
    fun selectLinesInRight(
        mp: FCPoint,
        divIndex: Int,
        datas: ArrayList<Double>,
        curIndex: Int
    ): Boolean {
        if (datas.size > 0) {
            val topY = getChartYInRight(divIndex, datas[curIndex])
            if (m_hScalePixel <= 1) {
                if (mp.y >= topY - 8 && mp.y <= topY + 8) {
                    return true
                }
            } else {
                val index = curIndex
                val scaleX = getChartX(index)
                var judgeTop = 0.0
                var judgeScaleX = scaleX.toDouble()
                if (mp.x >= scaleX) {
                    val leftIndex = curIndex + 1
                    if (curIndex < m_lastVisibleIndex) {
                        val rightValue = datas[leftIndex]
                        judgeTop = getChartYInRight(divIndex, rightValue).toDouble()
                    } else {
                        judgeTop = topY.toDouble()
                    }
                } else {
                    judgeScaleX = scaleX - m_hScalePixel
                    val rightIndex = curIndex - 1
                    if (curIndex > 0) {
                        val leftValue = datas[rightIndex]
                        judgeTop = getChartYInRight(divIndex, leftValue).toDouble()
                    } else {
                        judgeTop = topY.toDouble()
                    }
                }
                val lineWidth = 4.0
                var judgeX = 0.0
                var judgeY = 0.0
                var judgeW = 0.0
                var judgeH = 0.0
                if (judgeTop >= topY) {
                    judgeX = judgeScaleX
                    judgeY = topY - 2 - lineWidth
                    judgeW = m_hScalePixel
                    judgeH =
                        if (judgeTop - topY + lineWidth < 4) 4.0 else (judgeTop - topY) + 4 + lineWidth
                } else {
                    judgeX = judgeScaleX
                    judgeY = judgeTop - 2 - (lineWidth / 2)
                    judgeW = m_hScalePixel
                    judgeH =
                        if (topY - judgeTop + lineWidth < 4) 4.0 else (topY - judgeTop) + 4 + lineWidth
                }
                if ((mp.x >= judgeX) && (
                            mp.x <= judgeX + judgeW) && (
                            mp.y >= judgeY) && (
                            mp.y <= judgeY + judgeH)
                ) {
                    return true
                }
            }
        }
        return false
    }

    /**
     * 左滚
     * @params step 步长
     */
    fun scrollLeftChart(step: Int) {
        var step = step
        m_targetOldX = 0f
        m_targetOldX2 = 0f
        if (m_showCrossLine) {
            m_crossStopIndex = m_crossStopIndex - step
            if (m_crossStopIndex >= m_firstVisibleIndex) {
                step = 0
            } else if (m_crossStopIndex < 0) {
                m_crossStopIndex = 0
            }
        }
        if (step > 0) {
            val subIndex = m_lastVisibleIndex - m_firstVisibleIndex
            var fIndex = m_firstVisibleIndex - step
            if (fIndex < 0) {
                fIndex = 0
            }
            val eIndex = fIndex + subIndex
            m_firstVisibleIndex = fIndex
            m_lastVisibleIndex = eIndex
        }
        checkChartLastVisibleIndex()
        calculateChartMaxMin()
    }

    /**
     * 右滚
     * @params step 步长
     */
    fun scrollRightChart(step: Int) {
        var step = step
        m_targetOldX = 0f
        m_targetOldX2 = 0f
        val dataCount = m_datas!!.size
        if (m_showCrossLine) {
            m_crossStopIndex = m_crossStopIndex + step
            if (m_crossStopIndex <= m_lastVisibleIndex) {
                step = 0
            } else if (m_crossStopIndex > dataCount - 1) {
                m_crossStopIndex = dataCount - 1
            }
        }
        if (step > 0) {
            val subIndex = m_lastVisibleIndex - m_firstVisibleIndex
            var eIndex = m_lastVisibleIndex + step
            if (eIndex > dataCount - 1) {
                eIndex = dataCount - 1
            }
            val fIndex = eIndex - subIndex
            m_firstVisibleIndex = fIndex
            m_lastVisibleIndex = eIndex
        }
        checkChartLastVisibleIndex()
        calculateChartMaxMin()
    }

    /**
     * 图表的鼠标按下方法
     * @params firstTouch 是否第一次触摸
     * @params firstPoint 第一次触摸的坐标
     * @params secondTouch 是否第二次触摸
     * @params secondPoint 第二次触摸的坐标
     */
    fun touchDownChart(
        firstTouch: Boolean,
        firstPoint: FCPoint,
        secondTouch: Boolean,
        secondPoint: FCPoint?,
        clicks: Int
    ) {
        m_touchDownPoint = firstPoint
        m_crossStopIndex = getChartIndex(firstPoint)
        m_targetOldX = 0f
        m_targetOldX2 = 0f
        m_selectShape = ""
        m_selectShapeEx = ""
        m_sPlot = null
        if (m_datas!!.size > 0) {
            val selectedPlot = selectPlot(firstPoint)
            if (selectedPlot != null) {
                m_sPlot = selectedPlot
            }
            if (m_sPlot == null) {
                judgeSelectShape(firstPoint)
            }
        }
        if (clicks == 2) {
            m_showCrossLine = !m_showCrossLine
        }
    }

    /**
     * 图表的鼠标移动方法
     * @params firstTouch 是否第一次触摸
     * @params firstPoint 第一次触摸的坐标
     * @params secondTouch 是否第二次触摸
     * @params secondPoint 第二次触摸的坐标
     */
    fun touchMoveChart(
        firstTouch: Boolean,
        firstPoint: FCPoint,
        secondTouch: Boolean,
        secondPoint: FCPoint
    ) {
        if (m_datas!!.size == 0) {
            return
        }
        val mp = firstPoint
        m_targetOldX = 0f
        m_targetOldX2 = 0f
        m_crossStopIndex = getChartIndex(mp)
        m_touchPosition = mp
        val sPlot = m_sPlot
        if (firstTouch && sPlot != null) {
            val newIndex = getChartIndex(mp)
            if (newIndex >= 0 && newIndex < m_datas!!.size) {
                val newDate = getChartDateByIndex(newIndex)
                val newValue = getCandleDivValue(mp)
                if (m_selectPlotPoint == 0) {
                    sPlot.m_key1 = newDate
                    sPlot.m_value1 = newValue
                } else if (m_selectPlotPoint == 1) {
                    sPlot.m_key2 = newDate
                    sPlot.m_value2 = newValue
                } else if (m_selectPlotPoint == 2) {
                    sPlot.m_key3 = newDate
                    sPlot.m_value3 = newValue
                } else if (m_startMovePlot) {
                    val bValue = getCandleDivValue(m_touchDownPoint)
                    val bIndex = getChartIndex(m_touchDownPoint)
                    if (sPlot.m_key1 > 0) {
                        sPlot.m_value1 = sPlot.m_startValue1 + (newValue - bValue)
                        val startIndex1 = getChartIndexByDate(sPlot.m_startKey1)
                        var newIndex1 = startIndex1 + (newIndex - bIndex)
                        if (newIndex1 < 0) {
                            newIndex1 = 0
                        } else if (newIndex1 > m_datas!!.size - 1) {
                            newIndex1 = m_datas!!.size - 1
                        }
                        sPlot.m_key1 = getChartDateByIndex(newIndex1)
                    }
                    if (sPlot.m_key2 > 0) {
                        sPlot.m_value2 = sPlot.m_startValue2 + (newValue - bValue)
                        val startIndex2 = getChartIndexByDate(sPlot.m_startKey2)
                        var newIndex2 = startIndex2 + (newIndex - bIndex)
                        if (newIndex2 < 0) {
                            newIndex2 = 0
                        } else if (newIndex2 > m_datas!!.size - 1) {
                            newIndex2 = m_datas!!.size - 1
                        }
                        sPlot.m_key2 = getChartDateByIndex(newIndex2)
                    }
                    if (sPlot.m_key3 > 0) {
                        sPlot.m_value3 = sPlot.m_startValue3 + (newValue - bValue)
                        val startIndex3 = getChartIndexByDate(sPlot.m_startKey3)
                        var newIndex3 = startIndex3 + (newIndex - bIndex)
                        if (newIndex3 < 0) {
                            newIndex3 = 0
                        } else if (newIndex3 > m_datas!!.size - 1) {
                            newIndex3 = m_datas!!.size - 1
                        }
                        sPlot.m_key3 = getChartDateByIndex(newIndex3)
                    }
                }
            }
            return
        }
        if (firstTouch && secondTouch) {
            if (firstPoint.x > secondPoint.x) {
                m_firstTouchPointCache = secondPoint
                m_secondTouchPointCache = firstPoint
            } else {
                m_firstTouchPointCache = firstPoint
                m_secondTouchPointCache = secondPoint
            }
            if (m_firstTouchIndexCache == -1 ||
                m_secondTouchIndexCache == -1
            ) {
                m_firstTouchIndexCache = getChartIndex(m_firstTouchPointCache)
                m_secondTouchIndexCache = getChartIndex(m_secondTouchPointCache)
                m_firstIndexCache = m_firstVisibleIndex
                m_lastIndexCache = m_lastVisibleIndex
            }
        } else if (firstTouch) {
            m_secondTouchIndexCache = -1
            if (m_firstTouchIndexCache == -1) {
                m_firstTouchPointCache = firstPoint
                m_firstTouchIndexCache = getChartIndex(m_firstTouchPointCache)
                m_firstIndexCache = m_firstVisibleIndex
                m_lastIndexCache = m_lastVisibleIndex
                m_firstPaddingTop = m_candlePaddingTop
                m_firtstPaddingBottom = m_candlePaddingBottom
            }
        }
        if (firstTouch && secondTouch) {
            if (m_firstTouchIndexCache != -1 &&
                m_secondTouchIndexCache != -1
            ) {
                var fPoint = firstPoint
                var sPoint = secondPoint
                if (firstPoint.x > secondPoint.x) {
                    fPoint = secondPoint
                    sPoint = firstPoint
                }
                val subX = Math.abs(sPoint.x - fPoint.x).toDouble()
                val subIndex = Math.abs(m_secondTouchIndexCache - m_firstTouchIndexCache)
                if (subX > 0 && subIndex > 0) {
                    var newScalePixel = subX / subIndex
                    if (newScalePixel >= 3) {
                        val intScalePixel = (newScalePixel.toInt()).toDouble()
                        newScalePixel = intScalePixel
                    }
                    if (newScalePixel != m_hScalePixel) {
                        var newFirstIndex = m_firstTouchIndexCache
                        var thisX = fPoint.x.toDouble()
                        thisX -= newScalePixel
                        while (thisX > m_leftVScaleWidth + newScalePixel) {
                            newFirstIndex--
                            if (newFirstIndex < 0) {
                                newFirstIndex = 0
                                break
                            }
                            thisX -= newScalePixel
                        }
                        thisX = sPoint.x.toDouble()
                        var newSecondIndex = m_secondTouchIndexCache
                        thisX += newScalePixel
                        while (thisX < size.cx - m_rightVScaleWidth - newScalePixel) {
                            newSecondIndex++
                            if (newSecondIndex > m_datas!!.size - 1) {
                                newSecondIndex = m_datas!!.size - 1
                                break
                            }
                            thisX += newScalePixel
                        }
                        setChartVisibleIndex(newFirstIndex, newSecondIndex)
                        val maxVisibleRecord =
                            getChartMaxVisibleCount(m_hScalePixel, chartWorkAreaWidth.toDouble())
                        while (maxVisibleRecord <
                            m_lastVisibleIndex - m_firstVisibleIndex + 1 &&
                            m_lastVisibleIndex > m_firstVisibleIndex
                        ) {
                            m_lastVisibleIndex--
                        }
                        checkChartLastVisibleIndex()
                        resetChartVisibleRecord()
                        calculateChartMaxMin()
                    }
                }
            }
        } else if (firstTouch) {
            if (!m_autoFillHScale) {
                val subIndex =
                    ((m_firstTouchPointCache.x - firstPoint.x) / m_hScalePixel).toInt()
                if (m_allowDragChartDiv) {
                    m_candlePaddingTop =
                        m_firstPaddingTop - (m_firstTouchPointCache.y - firstPoint.y)
                    m_candlePaddingBottom =
                        m_firtstPaddingBottom + (m_firstTouchPointCache.y - firstPoint.y)
                }
                var fIndex = m_firstIndexCache + subIndex
                var lIndex = m_lastIndexCache + subIndex
                if (fIndex > m_datas!!.size - 1) {
                    fIndex = m_datas!!.size - 1
                    lIndex = m_datas!!.size - 1
                }
                m_firstVisibleIndex = fIndex
                m_lastVisibleIndex = lIndex
                checkChartLastVisibleIndex()
                calculateChartMaxMin()
            }
        }
    }

    /**
     * 更新布局方法
     */
    override fun update() {
        super.update()
        resetChartVisibleRecord()
        checkChartLastVisibleIndex()
        calculateChartMaxMin()
    }

    /**
     * 缩小
     */
    fun zoomOutChart() {
        if (!m_autoFillHScale) {
            var hScalePixel = m_hScalePixel
            val oldX = getChartX(m_crossStopIndex)
            if (m_targetOldX == 0f) {
                m_targetOldX = oldX.toFloat()
            }
            val pureH = chartWorkAreaWidth
            var oriMax = -1
            var max = -1
            var deal = 0
            val dataCount = m_datas!!.size
            var findex = m_firstVisibleIndex
            var lindex = m_lastVisibleIndex
            if (hScalePixel < pureH) {
                oriMax = getChartMaxVisibleCount(hScalePixel, pureH.toDouble())
                if (dataCount < oriMax) {
                    deal = 1
                }
                if (hScalePixel > 3) {
                    hScalePixel += 1.0
                } else {
                    if (hScalePixel == 1.0) {
                        hScalePixel = 2.0
                    } else {
                        hScalePixel = hScalePixel * 1.5
                        if (hScalePixel > 3) {
                            hScalePixel = (hScalePixel.toInt()).toDouble()
                        }
                    }
                }
                max = getChartMaxVisibleCount(hScalePixel, pureH.toDouble())
                if (dataCount >= max) {
                    if (deal == 1) {
                        lindex = dataCount - 1
                    }
                    findex = lindex - max + 1
                    if (findex < 0) {
                        findex = 0
                    }
                }
            }
            m_hScalePixel = hScalePixel
            if (true) {
                var sX = m_targetOldX
                findex = m_crossStopIndex
                while (sX >= m_leftVScaleWidth + m_hScalePixel / 2) {
                    findex = findex - 1
                    m_offsetX = (sX - m_leftVScaleWidth - (m_hScalePixel / 2)).toFloat()
                    sX = (sX - m_hScalePixel).toFloat()
                }
                findex = findex + 1
            }
            m_firstVisibleIndex = findex
            m_lastVisibleIndex = lindex
            checkChartLastVisibleIndex()
            calculateChartMaxMin()
        }
    }

    /**
     * 放大
     */
    fun zoomInChart() {
        if (!m_autoFillHScale) {
            var hScalePixel = m_hScalePixel
            val oldX = getChartX(m_crossStopIndex)
            if (m_targetOldX2 == 0f) {
                m_targetOldX2 = oldX.toFloat()
            }
            val pureH = chartWorkAreaWidth
            var max = -1
            val dataCount = m_datas!!.size
            var findex = m_firstVisibleIndex
            var lindex = m_lastVisibleIndex
            if (hScalePixel > 3) {
                hScalePixel -= 1.0
            } else {
                hScalePixel = hScalePixel * 2 / 3
                if (hScalePixel > 3) {
                    hScalePixel = (hScalePixel.toInt()).toDouble()
                }
            }
            max = getChartMaxVisibleCount(hScalePixel, pureH.toDouble())
            if (max >= dataCount) {
                if (hScalePixel < 1) {
                    hScalePixel = pureH / max.toDouble()
                }
                findex = 0
                lindex = dataCount - 1
            } else {
                findex = lindex - max + 1
                if (findex < 0) {
                    findex = 0
                }
            }
            m_hScalePixel = hScalePixel
            if (true) {
                var sX = m_targetOldX2
                findex = m_crossStopIndex
                while (sX >= m_leftVScaleWidth + m_hScalePixel / 2) {
                    findex = findex - 1
                    m_offsetX = (sX - m_leftVScaleWidth - (m_hScalePixel / 2)).toFloat()
                    sX = (sX - m_hScalePixel).toFloat()
                }
                findex = findex + 1
            }
            m_firstVisibleIndex = findex
            m_lastVisibleIndex = lindex
            checkChartLastVisibleIndex()
            calculateChartMaxMin()
        }
    }
}